Skip to content

Commit e241cf9

Browse files
committed
fix
1 parent 0a47ba1 commit e241cf9

File tree

10 files changed

+28480
-933
lines changed

10 files changed

+28480
-933
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"svg.preview.background": "transparent"
2+
"svg.preview.background": "transparent",
3+
"cSpell.words": ["moveend"]
34
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-openlayers7",
3-
"version": "0.3.74",
3+
"version": "0.3.75",
44
"author": {
55
"name": "Han-D-Peter",
66
"email": "jaesung.sound@gmail.com"

public/images/12314.JPG

3.18 MB
Loading

public/images/12371.JPG

3.24 MB
Loading
15.2 MB
Loading

src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
CustomPolyLine,
66
CustomPolygon,
77
CustomRectangle,
8+
ImageMarker,
89
} from "./lib/Map/layer/annotation";
910
import { InnerText } from "./lib/Map/Text";
1011
import { FullScreenFeature } from "./lib/Map/control/FullScreenFeature";
@@ -37,7 +38,6 @@ import { SyncMap } from "../src/lib/Map/SyncMapGroup/SyncMap";
3738
import _ from "lodash";
3839
import TestField from "./TestField";
3940
import json from "./sample.json";
40-
import ImageMarker from "./lib/Map/layer/annotation/ImageMarker";
4141

4242
icon.marker = "/images/marker-basic.png";
4343
icon.selected = "/images/marker-selected.png";

src/TestField.tsx

Lines changed: 123 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,129 @@
1+
import React from "react";
12
import { useMapEventHandler } from "./lib";
3+
import ImageMapForPixel from "./lib/Map/ImageMapForPixel/index";
24

35
const TestField = () => {
4-
useMapEventHandler({
5-
onDrag: () => console.log("drag"),
6-
});
7-
return <></>;
6+
// useMapEventHandler({
7+
// onDrag: () => console.log("drag"),
8+
// });
9+
10+
function getDegreeFromMoviePixel({
11+
width,
12+
height,
13+
targetPixelX,
14+
targetPixelY,
15+
focalLength,
16+
sensorSize,
17+
px,
18+
py,
19+
}: {
20+
width: number;
21+
height: number;
22+
targetPixelX: number;
23+
targetPixelY: number;
24+
focalLength: number;
25+
sensorSize: number;
26+
px: number;
27+
py: number;
28+
}) {
29+
const centerX = width / 2;
30+
const centerY = height / 2;
31+
32+
const targetX = targetPixelX;
33+
const targetY = targetPixelY;
34+
35+
const resultX = targetX - centerX;
36+
const resultY = -(centerY - targetY);
37+
38+
const distanceX = centerX * sensorSize - px;
39+
const distanceY = centerY * sensorSize - py;
40+
41+
const resultXLength = (resultX + 0.5) * sensorSize - distanceX;
42+
const resultYLength = (resultY + 0.5) * sensorSize - distanceY;
43+
44+
const radianGapX = Math.atan(resultXLength / focalLength);
45+
const radianGapY = Math.atan(resultYLength / focalLength);
46+
47+
const degreeGapX = (radianGapX * 180) / Math.PI;
48+
const degreeGapY = (radianGapY * 180) / Math.PI;
49+
50+
return {
51+
radianGapX,
52+
radianGapY,
53+
degreeGapX,
54+
degreeGapY,
55+
};
56+
}
57+
58+
function cal({
59+
width,
60+
height,
61+
targetPixelX,
62+
targetPixelY,
63+
focalLength,
64+
sensorSize,
65+
px,
66+
py,
67+
}: {
68+
width: number;
69+
height: number;
70+
targetPixelX: number;
71+
targetPixelY: number;
72+
focalLength: number;
73+
sensorSize: number;
74+
px: number;
75+
py: number;
76+
}) {}
77+
78+
return (
79+
<ImageMapForPixel
80+
image={{
81+
src: "/images/12314.JPG",
82+
width: 5472,
83+
height: 3648,
84+
}}
85+
height="500px"
86+
width="500px"
87+
fullscreenControl
88+
onClick={(pixel) => {
89+
// 4096
90+
// 2730
91+
console.log("pixel", pixel);
92+
// const result = getDegreeFromMoviePixel({
93+
// width: 5472,
94+
// height: 3648,
95+
// targetPixelX: 0,
96+
// targetPixelY: 0,
97+
// focalLength: 8.65925579685115387463,
98+
// sensorSize: 0.00234527,
99+
// px: 6.30743141004738383515,
100+
// py: 4.23323095598362719727,
101+
// });
102+
103+
// console.log("result", result);
104+
// const centerX = 5472 / 2;
105+
// const centerY = 3648 / 2;
106+
107+
// const targetX = pixel.x;
108+
// const targetY = pixel.y;
109+
110+
// const resultX = targetX - centerX;
111+
// const resultY = centerY - targetY;
112+
113+
// const focalLength = 8.6;
114+
// const sensorSize = 0.00241;
115+
116+
// const radianGapX = Math.atan((resultX * sensorSize) / focalLength);
117+
// const radianGapY = Math.atan((resultY * sensorSize) / focalLength);
118+
119+
// const degreeGapX = (radianGapX * 180) / Math.PI;
120+
// const degreeGapY = (radianGapY * 180) / Math.PI;
121+
122+
// console.log("radianGapX radianGapY", radianGapX, radianGapY);
123+
// console.log("degreeGapX degreeGapY", degreeGapX, degreeGapY);
124+
}}
125+
></ImageMapForPixel>
126+
);
8127
};
9128

10129
export default TestField;
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import { Map, MapBrowserEvent, View } from "ol";
2+
import { ReactNode, useEffect, useId, useState, useRef } from "react";
3+
import { defaults as defaultControls } from "ol/control";
4+
import TileLayer from "ol/layer/Tile";
5+
import { ImageStatic, OSM } from "ol/source";
6+
import { fromLonLat } from "ol/proj";
7+
import { Image } from "ol/layer";
8+
9+
interface ImageMapForPixelProps {
10+
/**
11+
* @default "1000px"
12+
*/
13+
height?: string;
14+
15+
image: {
16+
src: string;
17+
width: number;
18+
height: number;
19+
};
20+
21+
/**
22+
* @default "1000px"
23+
*/
24+
width?: string;
25+
fullscreenControl?: boolean;
26+
children?: ReactNode;
27+
28+
onClick?: (pixel: { x: number; y: number }) => void;
29+
}
30+
31+
export default function ImageMapForPixel({
32+
height,
33+
image,
34+
width,
35+
fullscreenControl,
36+
children,
37+
onClick,
38+
}: ImageMapForPixelProps) {
39+
const id = useId();
40+
const mapId = `react-openlayers-map-${id}`;
41+
const mapObj = useRef<Map>(
42+
new Map({
43+
view: new View({
44+
center: fromLonLat([0, 0]),
45+
}),
46+
controls: defaultControls({
47+
zoom: false,
48+
rotate: true,
49+
}).extend([]),
50+
layers: [
51+
new TileLayer({
52+
source: new OSM({
53+
crossOrigin: "anonymous",
54+
}),
55+
}),
56+
],
57+
})
58+
);
59+
60+
const [imagePixel, setImagePixel] = useState<{ x: number; y: number } | null>(
61+
null
62+
);
63+
64+
if (imagePixel && onClick) {
65+
onClick(imagePixel);
66+
}
67+
68+
useEffect(() => {
69+
const mapRef = mapObj.current;
70+
71+
mapRef.setTarget(mapId);
72+
73+
function getImagePixel(event: MapBrowserEvent<any>) {
74+
// 클릭한 포인트의 좌표를 얻음
75+
var clickedCoordinate = event.coordinate;
76+
77+
// 포인트 좌표를 픽셀 좌표로 변환
78+
var clickedPixel = clickedCoordinate;
79+
80+
const heightdigit = `${image.height}`;
81+
const heightbycount = heightdigit.length - 2;
82+
const rightdigit = `${image.width}`;
83+
const rightbycount = rightdigit.length - 2;
84+
// 픽셀 좌표 출력
85+
86+
const xPosition = (clickedPixel[0] * 10 ** rightbycount).toFixed(0);
87+
const yPosition = (
88+
image.height -
89+
clickedPixel[1] * 10 ** heightbycount
90+
).toFixed(0);
91+
92+
if (
93+
Number(xPosition) <= image.width &&
94+
Number(yPosition) <= image.height &&
95+
Number(xPosition) > 0 &&
96+
Number(yPosition) > 0
97+
) {
98+
setImagePixel({
99+
x: Number(xPosition),
100+
y: Number(yPosition),
101+
});
102+
}
103+
}
104+
105+
mapRef.on("click", getImagePixel);
106+
107+
return () => {
108+
mapRef.setTarget(undefined);
109+
mapRef.setLayers([]);
110+
mapRef.un("click", getImagePixel);
111+
};
112+
}, [image.height, image.width, mapId]);
113+
114+
useEffect(() => {
115+
const mapRef = mapObj.current;
116+
117+
// image.height는 3648
118+
const heightdigit = `${image.height}`;
119+
const heightbycount = heightdigit.length - 2;
120+
121+
const bottomPosition = Number(
122+
(image.height / 10 ** heightbycount).toFixed(heightbycount)
123+
);
124+
125+
// image.width는 5472
126+
const rightdigit = `${image.width}`;
127+
const rightbycount = rightdigit.length - 2;
128+
const rightPosition = Number(
129+
(image.width / 10 ** rightbycount).toFixed(rightbycount)
130+
);
131+
132+
const imageLayer = new Image({
133+
source: new ImageStatic({
134+
url: image.src,
135+
imageSize: [image.width, image.height],
136+
imageExtent: [0, 0, rightPosition, bottomPosition],
137+
}),
138+
});
139+
140+
mapRef.addLayer(imageLayer);
141+
mapRef.getView().fit(imageLayer.getSource()?.getImageExtent()!, {
142+
duration: 1000, // 애니메이션 지속 시간 (밀리초)
143+
});
144+
return () => {
145+
mapRef.removeLayer(imageLayer);
146+
};
147+
}, [image]);
148+
149+
return (
150+
<div
151+
id={mapId}
152+
className="react-openlayers-map-container"
153+
style={{ width, height }}
154+
>
155+
{children}
156+
</div>
157+
);
158+
}

src/lib/Map/layer/annotation/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export * from "./Polygon";
1010
export * from "./PolyLine";
1111
export * from "./Rectangle";
1212
export * from "./TextMarker";
13+
export * from "./ImageMarker";
1314

1415
export interface Annotation {
1516
color?: keyof typeof ANNOTATION_COLOR;

src/sample.json

Lines changed: 28194 additions & 926 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)