kmap-ui
Version:
A components of zmap base on vue2.X
230 lines (212 loc) • 7.65 kB
JavaScript
/* 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 }