@mint-ui/map
Version:
- React map library - Control various map with one interface - Google, Naver, Kakao map supported now - Typescript supported - Canvas marker supported
317 lines (244 loc) • 9.03 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var geo = require('./geo.js');
var LinePoints =
/** @class */
function () {
function LinePoints(x1, y1, x2, y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
return LinePoints;
}();
var PositionMirror =
/** @class */
function () {
function PositionMirror(lat, lng) {
this.lat = lat;
this.lng = lng;
}
return PositionMirror;
}();
var PolygonCalculator =
/** @class */
function () {
function PolygonCalculator() {}
PolygonCalculator.getRegionInfo = function (positions) {
var maxX, minX, maxY, minY;
for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {
var pos = positions_1[_i];
if (maxX === undefined || pos.lat > maxX) {
maxX = pos.lat;
}
if (minX === undefined || pos.lat < minX) {
minX = pos.lat;
}
if (maxY === undefined || pos.lng > maxY) {
maxY = pos.lng;
}
if (minY === undefined || pos.lng < minY) {
minY = pos.lng;
}
}
return {
maxLat: maxX,
minLat: minX,
maxLng: maxY,
minLng: minY,
centerLat: minX && maxX ? minX + (maxX - minX) / 2 : undefined,
centerLng: minY && maxY ? minY + (maxY - minY) / 2 : undefined
};
};
PolygonCalculator.getRegionStart = function (positions) {
var info = this.getRegionInfo(positions);
if (info.minLat && info.minLng) {
return new PositionMirror(info.minLat, info.minLng);
}
throw new Error('Calculate RegionStart Error!!!');
};
PolygonCalculator.getRegionEnd = function (positions) {
var info = this.getRegionInfo(positions);
if (info.maxLat && info.maxLng) {
return new PositionMirror(info.maxLat, info.maxLng);
}
throw new Error('Calculate RegionEnd Error!!!');
};
PolygonCalculator.getCenter = function (positions) {
var info = this.getRegionInfo(positions);
if (info.centerLat && info.centerLng) {
return new PositionMirror(info.centerLat, info.centerLng);
}
throw new Error('Calculate Center Error!!!');
};
PolygonCalculator.intersects = function (positions1, positions2) {
var lines = [];
for (var i = 0; i < positions2.length - 1; i++) {
lines.push(this.convertPositionToPoints(positions2[i], positions2[i + 1]));
}
for (var i = 0; i < positions1.length - 1; i++) {
var targetLinePoints = this.convertPositionToPoints(positions1[i], positions1[i + 1]);
if (this.findCrossPoint(lines, targetLinePoints)) {
return true;
}
}
return false;
};
PolygonCalculator.getIncludedPositions = function (polygon, position) {
var targets = Array.isArray(position) ? position : [position];
var result = [];
var maxX = Math.max.apply(Math, polygon.map(function (pos) {
return pos.lng;
})) + 1;
var lines = this.convertPolygonToLinePoints(polygon);
for (var _i = 0, targets_1 = targets; _i < targets_1.length; _i++) {
var target = targets_1[_i]; //x 축으로 긴 직선과 폴리곤 path 와의 교차 수 비교
var tempLine = this.convertPositionToPoints(target, new PositionMirror(target.lat, maxX));
var crossPoints = this.getCrossPointAll(lines, tempLine); // console.log('crossPoints',crossPoints);
if (crossPoints.length > 0 && crossPoints.length % 2 != 0) {
result.push(target);
}
}
return result;
};
PolygonCalculator.convertPolygonToLinePoints = function (polygon) {
var lines = [];
for (var i = 0; i < polygon.length; i++) {
lines.push(this.convertPositionToPoints(polygon[i], polygon[i + 1 === polygon.length ? 0 : i + 1]));
}
return lines;
};
PolygonCalculator.convertPositionToPoints = function (pos1, pos2) {
return new LinePoints(pos1.lng, pos1.lat, pos2.lng, pos2.lat);
}; //두 직선의 교점 구하기
PolygonCalculator.getCrossPoint = function (sr, tr) {
var p1 = (sr.x1 - sr.x2) * (tr.y1 - tr.y2) - (sr.y1 - sr.y2) * (tr.x1 - tr.x2); //분모로 사용됨
// p1 ==0 이면 평행선 또는 일치 이므로 제외(분모)
if (p1 != 0) {
var x = ((sr.x1 * sr.y2 - sr.y1 * sr.x2) * (tr.x1 - tr.x2) - (sr.x1 - sr.x2) * (tr.x1 * tr.y2 - tr.y1 * tr.x2)) / p1;
var y = ((sr.x1 * sr.y2 - sr.y1 * sr.x2) * (tr.y1 - tr.y2) - (sr.y1 - sr.y2) * (tr.x1 * tr.y2 - tr.y1 * tr.x2)) / p1;
if (this.toFixedPosition((x - sr.x1) * (x - sr.x2)) <= 0 && this.toFixedPosition((y - sr.y1) * (y - sr.y2)) <= 0 //교점이 1선분 위에 있고
&& this.toFixedPosition((x - tr.x1) * (x - tr.x2)) <= 0 && this.toFixedPosition((y - tr.y1) * (y - tr.y2)) <= 0 //교점이 2선분 위에 있을경우
) {
return {
x: x,
y: y
};
}
}
};
PolygonCalculator.toFixedPosition = function (n) {
return Number(n.toFixed(15));
};
PolygonCalculator.getCrossPointAll = function (sr, tr) {
var result = [];
for (var _i = 0, sr_1 = sr; _i < sr_1.length; _i++) {
var tmp = sr_1[_i];
var p = this.getCrossPoint(tmp, tr);
if (p) {
result.push(p);
}
}
return result;
};
PolygonCalculator.findCrossPoint = function (sr, tr) {
for (var _i = 0, sr_2 = sr; _i < sr_2.length; _i++) {
var tmp = sr_2[_i]; //교점이 있으면 true
if (this.getCrossPoint(tmp, tr)) {
return true;
}
}
return false;
};
PolygonCalculator.simplifyPoints = function (polygon, tolerance, _lastRepeated) {
return this.simplify(this.pathCleaning(polygon), tolerance !== undefined ? tolerance : this.TOLERANCE_NAVER_STYLE);
};
PolygonCalculator.pathCleaning = function (polygon) {
if (polygon.length < 3) {
return polygon;
}
var main = polygon[0];
var delCount = 0;
for (var i = polygon.length - 1; i >= 0; i--) {
if (main.equals(polygon[i])) {
delCount += 1;
} else {
break;
}
}
delCount > 0 && polygon.splice(polygon.length - delCount, delCount);
var out = [];
out.push.apply(out, polygon);
return out;
};
PolygonCalculator.simplify = function (points, tolerance) {
if (points.length <= 2) {
return points;
}
var dMax = 0;
var index = 0; // Find the point with the maximum distance from the line segment
var denominator = this.perpendicularDistanceDenominator(points[0], points[points.length - 1]);
for (var i = 1; i < points.length - 1; i++) {
var d = this.perpendicularDistance(points[i], points[0], points[points.length - 1], denominator);
if (d > dMax) {
dMax = d;
index = i;
}
} // If the maximum distance is greater than the tolerance, recursively simplify
if (dMax > tolerance) {
var left = this.simplify(points.slice(0, index + 1), tolerance);
var right = this.simplify(points.slice(index), tolerance); // Concatenate the simplified left and right segments
return left.slice(0, left.length - 1).concat(right);
} else {
// If the maximum distance is less than or equal to the tolerance, return the endpoints
return [points[0], points[points.length - 1]];
}
};
PolygonCalculator.perpendicularDistanceDenominator = function (lineStart, lineEnd) {
var x1 = lineStart.x,
y1 = lineStart.y;
var x2 = lineEnd.x,
y2 = lineEnd.y;
return Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2));
}; // Calculate the perpendicular distance from a point to a line segment
PolygonCalculator.perpendicularDistance = function (point, lineStart, lineEnd, denominator) {
var x = point.x;
var y = point.y;
var x1 = lineStart.x;
var y1 = lineStart.y;
var x2 = lineEnd.x;
var y2 = lineEnd.y;
return Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1) / denominator;
};
PolygonCalculator.calculatePolygonSize = function (polygon, innerPolygons) {
var _this = this;
var outer = this.calculatePolygonSizeMain(polygon);
var inner = 0;
innerPolygons && innerPolygons.map(function (innerPolygon) {
inner += _this.calculatePolygonSizeMain(innerPolygon);
});
return outer - inner;
};
PolygonCalculator.calculatePolygonSizeMain = function (polygon) {
var vertices = polygon.map(function (pos) {
return {
x: geo.GeoCalulator.convertLongitudeToMeterValue(pos.lat, pos.lng),
y: geo.GeoCalulator.convertLatitudeToMeterValue(pos.lat)
};
});
var n = vertices.length;
var sum = 0;
for (var i = 0; i < n; i++) {
var currentVertex = vertices[i];
var nextVertex = vertices[(i + 1) % n];
sum += currentVertex.x * nextVertex.y - currentVertex.y * nextVertex.x;
}
var area = Math.abs(sum) / 2;
return area;
};
PolygonCalculator.TOLERANCE_NAVER_STYLE = 1;
PolygonCalculator.TOLERANCE_GOOGLE_STYLE = 1;
return PolygonCalculator;
}();
exports.PolygonCalculator = PolygonCalculator;