/
shape-detector.tsx
115 lines (105 loc) · 3.12 KB
/
shape-detector.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import * as ol from 'openlayers'
import * as turf from '@turf/turf'
import { GeometryJSON } from '../geometry'
import Shape from './shape'
/**
* Detects shapes of GeometryJSON objects by evaluating their geometric contents
*/
class ShapeDetector {
private geoFormat: ol.format.GeoJSON
/**
* Constructs an instance of the ShapeDetector
*/
constructor() {
this.geoFormat = new ol.format.GeoJSON()
}
/**
* Gets the shape of GeometryJSON object
* @param geoJSON - GeometryJSON object
* @returns Shape of geometry
*/
shapeFromGeoJSON(geoJSON: GeometryJSON): Shape {
const feature = this.geoFormat.readFeature(geoJSON)
return this.shapeFromFeature(feature)
}
/**
* Gets the shape of an Open Layers feature
* @param feature - Open Layers feature
* @returns Shape of geometry
*/
shapeFromFeature(feature: ol.Feature): Shape {
if (this.isLineFeature(feature)) {
return 'Line'
} else if (this.isBoundingBoxFeature(feature)) {
return 'Bounding Box'
} else if (this.isPointFeature(feature)) {
return 'Point'
} else if (this.isPointRadiusFeature(feature)) {
return 'Point Radius'
} else {
return 'Polygon'
}
}
/**
* Checks if feature matches shape
* @param feature - Open Layers feature
* @returns true if geometry is a line
*/
isLineFeature(feature: ol.Feature): boolean {
return feature.getGeometry().getType() === 'LineString'
}
/**
* Checks if feature matches shape
* @param feature - Open Layers feature
* @returns true if geometry is a point
*/
isPointFeature(feature: ol.Feature): boolean {
return (
feature.getGeometry().getType() === 'Point' &&
(feature.get('buffer') === undefined || feature.get('buffer') <= 0)
)
}
/**
* Checks if feature matches shape
* @param feature - Open Layers feature
* @returns true if geometry is a bounding box
*/
isBoundingBoxFeature(feature: ol.Feature): boolean {
if (!this.isPolygonFeature(feature)) {
return false
} else {
const coordinates = (feature.getGeometry() as ol.geom.Polygon).getCoordinates()[0]
const extent = feature.getGeometry().getExtent()
const expectedCoordinates = (turf.bboxPolygon(extent)
.geometry as turf.Polygon).coordinates[0] as [number, number][]
return (
coordinates.length === 5 &&
expectedCoordinates.every(expectedPoint =>
coordinates.some(
point =>
point[0] === expectedPoint[0] && point[1] === expectedPoint[1]
)
)
)
}
}
/**
* Checks if feature matches shape
* @param feature - Open Layers feature
* @returns true if geometry is a point radius
*/
isPointRadiusFeature(feature: ol.Feature): boolean {
return (
feature.getGeometry().getType() === 'Point' && feature.get('buffer') > 0
)
}
/**
* Checks if feature matches shape
* @param feature - Open Layers feature
* @returns true if geometry is a polygon
*/
isPolygonFeature(feature: ol.Feature): boolean {
return feature.getGeometry().getType() === 'Polygon'
}
}
export default ShapeDetector