mirror of
https://github.com/Viglino/ol-games.git
synced 2026-01-25 15:35:19 +00:00
140 lines
4.3 KiB
JavaScript
140 lines
4.3 KiB
JavaScript
/* Copyright (c) 2017 Jean-Marc VIGLINO,
|
|
released under the CeCILL-B license (French BSD license)
|
|
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
|
|
|
|
@example http://www.hexographer.com/
|
|
|
|
*/
|
|
import ol_Object from 'ol/Object'
|
|
import ol_source_Vector from 'ol/source/Vector'
|
|
|
|
import {ol_coordinate_equal} from 'ol-ext/geom/GeomUtils'
|
|
import {ol_coordinate_dist2d} from 'ol-ext/geom/GeomUtils'
|
|
|
|
/** Vector graph
|
|
* A graph base on a vector source where edges are polylines features of the source.
|
|
*
|
|
* @constructor ol.Graph
|
|
* @extends {ol.Object}
|
|
* @param {*} options
|
|
* @param {ol.source.Vector} options.source the vector source must be configured with useSpatialIndex set to true.
|
|
*/
|
|
var ol_graph_Vector = class olgraphVector extends ol_Object {
|
|
constructor(options) {
|
|
options = options || {}
|
|
|
|
super(options)
|
|
|
|
this.edges = options.source || new ol_source_Vector({ useSpatialIndex: true })
|
|
this.edges.on('changefeature', this.changeEdge.bind(this))
|
|
this.edges.on('addfeature', this.addEdge.bind(this))
|
|
this.edges.on('removefeature', this.removeEdge.bind(this))
|
|
}
|
|
/** Get the source of the graph
|
|
* @return {ol.source.Vector}
|
|
*/
|
|
getSource() {
|
|
return this.edges
|
|
}
|
|
/** Triggered when a feature is updated.
|
|
*/
|
|
changeEdge( /*e*/) {
|
|
}
|
|
/** Triggered when a feature is added.
|
|
*/
|
|
addEdge( /*e*/) {
|
|
}
|
|
/** Triggered when a feature is removed.
|
|
*/
|
|
removeEdge( /*e*/) {
|
|
}
|
|
/** Get connections
|
|
* @param {node} node to find connections to
|
|
* @param {bool} inout if you want to get an object with in/out connections
|
|
* @param {function} filter A function that takes an ol.Feature and returns true if the feature may be selected or false otherwise.
|
|
* @return {Array<ol.Feature>|Object} list of connected features or an object with a in and out property
|
|
*/
|
|
getConnections(node, inout, filter) {
|
|
var p = node.getCoordinates ? node.getCoordinates() : node
|
|
var features = this.edges.getFeaturesInExtent([p[0] - 1, p[1] - 1, p[0] + 1, p[1] + 1])
|
|
var con = inout ? { 'in': [], 'out': [] } : []
|
|
// Verify connection
|
|
for (var i = 0, c; c = features[i]; i++)
|
|
if (!filter || filter(c)) {
|
|
if (ol_coordinate_equal(p, c.getGeometry().getFirstCoordinate())) {
|
|
if (inout)
|
|
con.out.push(c)
|
|
else
|
|
con.push(c)
|
|
} else if (ol_coordinate_equal(p, c.getGeometry().getLastCoordinate())) {
|
|
if (inout)
|
|
con.in.push(c)
|
|
else
|
|
con.push(c)
|
|
}
|
|
}
|
|
return con
|
|
}
|
|
/** Get edges connected to an other one
|
|
* @param {node} edge to find connections to
|
|
* @param {bool} inout if you want to get an object with in/out connections
|
|
* @return {Array} list of connected features (first node / last node)
|
|
*/
|
|
getConnected(edge, inout) {
|
|
var con = []
|
|
var filter = function (f) { return (f === edge) }
|
|
con[0] = this.getConnections(edge.getGeometry().getFirstCoordinate(), inout, filter)
|
|
con[1] = this.getConnections(edge.getGeometry().getLastCoordinate(), inout, filter)
|
|
return con
|
|
}
|
|
/** Filter if an object is an edge (linestring)
|
|
* @param {ol.Feature} f
|
|
* @return {boolean} true if f is not an edge (filtered)
|
|
*/
|
|
filterEdge(f) {
|
|
return (f.getGeometry().getType() === "LineString")
|
|
}
|
|
/** Check if a feature is an edge (linestring)
|
|
* @param {ol.Feature} f
|
|
* @return {boolean} true if f is an edge
|
|
*/
|
|
isEdge(f) {
|
|
return (f.getGeometry().getType() !== "LineString")
|
|
}
|
|
/** Get nearest neighbor at a coord
|
|
* @param {ol.coordinate} p coord to get neighbor
|
|
* @param {number} dist max dist to search to
|
|
* @return {ol.Feature}
|
|
*/
|
|
getNN(p, dist) {
|
|
// Not so efficient
|
|
// return this.edges.getClosestFeatureToCoordinate(p);
|
|
var f0
|
|
// Loop up to dist = 1e10
|
|
if (!dist) {
|
|
for (var i = 1; i < 1e10; i *= 10) {
|
|
f0 = this.getNN(p, i)
|
|
if (f0)
|
|
break
|
|
}
|
|
} else {
|
|
// Search closest
|
|
var features = this.edges.getFeaturesInExtent([p[0] - dist, p[1] - dist, p[0] + dist, p[1] + dist])
|
|
var dmin = Infinity
|
|
features.forEach(function (f) {
|
|
var n = f.getGeometry().getClosestPoint(p)
|
|
var d = ol_coordinate_dist2d(n, p)
|
|
if (d < dmin) {
|
|
dmin = d
|
|
f0 = f
|
|
}
|
|
})
|
|
if (dmin > dist)
|
|
f0 = null
|
|
}
|
|
return f0
|
|
}
|
|
}
|
|
|
|
export default ol_graph_Vector
|