UNPKG

kmap-ui

Version:

A components of zmap base on vue2.X

230 lines (212 loc) 7.65 kB
/* Copyright (c) 2016 Jean-Marc VIGLINO, released under the CeCILL-B license (French BSD license) (http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt). Usefull function to handle geometric operations */ import {getCenter as ol_extent_getCenter} from 'ol/extent' /** Distance beetween 2 points * Usefull geometric functions * @param {ol.Coordinate} p1 first point * @param {ol.Coordinate} p2 second point * @return {number} distance */ var ol_coordinate_dist2d = function(p1, p2) { var dx = p1[0]-p2[0]; var dy = p1[1]-p2[1]; return Math.sqrt(dx*dx+dy*dy); } /** 2 points are equal * Usefull geometric functions * @param {ol.Coordinate} p1 first point * @param {ol.Coordinate} p2 second point * @return {boolean} */ var ol_coordinate_equal = function(p1, p2) { return (p1[0]==p2[0] && p1[1]==p2[1]); } /** Get center coordinate of a feature * @param {ol.Feature} f * @return {ol.coordinate} the center */ var ol_coordinate_getFeatureCenter = function(f) { return ol_coordinate_getGeomCenter (f.getGeometry()); }; /** Get center coordinate of a geometry * @param {ol.Feature} geom * @return {ol.Coordinate} the center */ var ol_coordinate_getGeomCenter = function(geom) { switch (geom.getType()) { case 'Point': return geom.getCoordinates(); case "MultiPolygon": geom = geom.getPolygon(0); // fallthrough case "Polygon": return geom.getInteriorPoint().getCoordinates(); default: return geom.getClosestPoint(ol_extent_getCenter(geom.getExtent())); } }; /** Offset a polyline * @param {Array<ol.Coordinate>} coords * @param {number} offset * @return {Array<ol.Coordinate>} resulting coord * @see http://stackoverflow.com/a/11970006/796832 * @see https://drive.google.com/viewerng/viewer?a=v&pid=sites&srcid=ZGVmYXVsdGRvbWFpbnxqa2dhZGdldHN0b3JlfGd4OjQ4MzI5M2Y0MjNmNzI2MjY */ var ol_coordinate_offsetCoords = function (coords, offset) { var path = []; var N = coords.length-1; var max = N; var mi, mi1, li, li1, ri, ri1, si, si1, Xi1, Yi1; var p0, p1, p2; var isClosed = ol_coordinate_equal(coords[0],coords[N]); if (!isClosed) { p0 = coords[0]; p1 = coords[1]; p2 = [ p0[0] + (p1[1] - p0[1]) / ol_coordinate_dist2d(p0,p1) *offset, p0[1] - (p1[0] - p0[0]) / ol_coordinate_dist2d(p0,p1) *offset ]; path.push(p2); coords.push(coords[N]) N++; max--; } for (var i = 0; i < max; i++) { p0 = coords[i]; p1 = coords[(i+1) % N]; p2 = coords[(i+2) % N]; mi = (p1[1] - p0[1])/(p1[0] - p0[0]); mi1 = (p2[1] - p1[1])/(p2[0] - p1[0]); // Prevent alignements if (Math.abs(mi-mi1) > 1e-10) { li = Math.sqrt((p1[0] - p0[0])*(p1[0] - p0[0])+(p1[1] - p0[1])*(p1[1] - p0[1])); li1 = Math.sqrt((p2[0] - p1[0])*(p2[0] - p1[0])+(p2[1] - p1[1])*(p2[1] - p1[1])); ri = p0[0] + offset*(p1[1] - p0[1])/li; ri1 = p1[0] + offset*(p2[1] - p1[1])/li1; si = p0[1] - offset*(p1[0] - p0[0])/li; si1 = p1[1] - offset*(p2[0] - p1[0])/li1; Xi1 = (mi1*ri1-mi*ri+si-si1) / (mi1-mi); Yi1 = (mi*mi1*(ri1-ri)+mi1*si-mi*si1) / (mi1-mi); // Correction for vertical lines if(p1[0] - p0[0] == 0) { Xi1 = p1[0] + offset*(p1[1] - p0[1])/Math.abs(p1[1] - p0[1]); Yi1 = mi1*Xi1 - mi1*ri1 + si1; } if (p2[0] - p1[0] == 0 ) { Xi1 = p2[0] + offset*(p2[1] - p1[1])/Math.abs(p2[1] - p1[1]); Yi1 = mi*Xi1 - mi*ri + si; } path.push([Xi1, Yi1]); } } if (isClosed) { path.push(path[0]); } else { coords.pop(); p0 = coords[coords.length-1]; p1 = coords[coords.length-2]; p2 = [ p0[0] - (p1[1] - p0[1]) / ol_coordinate_dist2d(p0,p1) *offset, p0[1] + (p1[0] - p0[0]) / ol_coordinate_dist2d(p0,p1) *offset ]; path.push(p2); } return path; } /** Find the segment a point belongs to * @param {ol.Coordinate} pt * @param {Array<ol.Coordinate>} coords * @return {} the index (-1 if not found) and the segment */ var ol_coordinate_findSegment = function (pt, coords) { for (var i=0; i<coords.length-1; i++) { var p0 = coords[i]; var p1 = coords[i+1]; if (ol_coordinate_equal(pt, p0) || ol_coordinate_equal(pt, p1)) { return { index:1, segment: [p0,p1] }; } else { var d0 = ol_coordinate_dist2d(p0,p1); var v0 = [ (p1[0] - p0[0]) / d0, (p1[1] - p0[1]) / d0 ]; var d1 = ol_coordinate_dist2d(p0,pt); var v1 = [ (pt[0] - p0[0]) / d1, (pt[1] - p0[1]) / d1 ]; if (Math.abs(v0[0]*v1[1] - v0[1]*v1[0]) < 1e-10) { return { index:1, segment: [p0,p1] }; } } } return { index: -1 }; }; /** * Split a Polygon geom with horizontal lines * @param {Array<ol.Coordinate>} geom * @param {number} y the y to split * @param {number} n contour index * @return {Array<Array<ol.Coordinate>>} */ var ol_coordinate_splitH = function (geom, y, n) { var x, abs; var list = []; for (var i=0; i<geom.length-1; i++) { // Hole separator? if (!geom[i].length || !geom[i+1].length) continue; // Intersect if (geom[i][1]<=y && geom[i+1][1]>y || geom[i][1]>=y && geom[i+1][1]<y) { abs = (y-geom[i][1]) / (geom[i+1][1]-geom[i][1]); x = abs * (geom[i+1][0]-geom[i][0]) + geom[i][0]; list.push ({ contour: n, index: i, pt: [x,y], abs: abs }); } } // Sort x list.sort(function(a,b) { return a.pt[0] - b.pt[0] }); // Horizontal segment var result = []; for (var j=0; j<list.length-1; j += 2) { result.push([list[j], list[j+1]]) } return result; }; import ol_geom_LineString from 'ol/geom/LineString' import ol_geom_LinearRing from 'ol/geom/LinearRing' import ol_geom_MultiLineString from 'ol/geom/MultiLineString' import ol_geom_MultiPoint from 'ol/geom/MultiPoint' import ol_geom_MultiPolygon from 'ol/geom/MultiPolygon' import ol_geom_Point from 'ol/geom/Point' import ol_geom_Polygon from 'ol/geom/Polygon' /** Create a geometry given a type and coordinates */ var ol_geom_createFromType = function (type, coordinates) { switch (type) { case 'LineString': return new ol_geom_LineString(coordinates); case 'LinearRing': return new ol_geom_LinearRing(coordinates); case 'MultiLineString': return new ol_geom_MultiLineString(coordinates); case 'MultiPoint': return new ol_geom_MultiPoint(coordinates); case 'MultiPolygon': return new ol_geom_MultiPolygon(coordinates); case 'Point': return new ol_geom_Point(coordinates); case 'Polygon': return new ol_geom_Polygon(coordinates); default: console.error('[createFromType] Unsupported type: '+type); return null; } }; export {ol_geom_createFromType} export {ol_coordinate_dist2d, ol_coordinate_equal, ol_coordinate_findSegment, ol_coordinate_getFeatureCenter, ol_coordinate_getGeomCenter, ol_coordinate_offsetCoords, ol_coordinate_splitH} /** Intersect 2 lines * @param {Arrar<ol.coordinate>} d1 * @param {Arrar<ol.coordinate>} d2 */ var ol_coordinate_getIntersectionPoint = function (d1, d2) { var d1x = d1[1][0] - d1[0][0]; var d1y = d1[1][1] - d1[0][1]; var d2x = d2[1][0] - d2[0][0]; var d2y = d2[1][1] - d2[0][1]; var det = d1x * d2y - d1y * d2x; if (det != 0) { var k = (d1x * d1[0][1] - d1x * d2[0][1] - d1y * d1[0][0] + d1y * d2[0][0]) / det; return [d2[0][0] + k*d2x, d2[0][1] + k*d2y]; } else { return false; } }; export { ol_coordinate_getIntersectionPoint }