UNPKG

@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
'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;