Created
February 7, 2021 17:15
-
-
Save iamgeoknight/bf0ca802c019fa22de47bc7f5df87e8f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Create a Draw interaction for LineString and Polygon | |
*/ | |
class Draw { | |
//Constructor accepts geometry type, map object and vector layer | |
constructor(type, map, vector_layer) { | |
this.map = map; | |
this.vector_layer = vector_layer; | |
this.draw = new ol.interaction.Draw({ | |
type: type, | |
stopClick: true | |
}); | |
this.draw.on('drawstart', this.onDrawStart); | |
this.draw.on('drawend', this.onDrawEnd); | |
this.map.addInteraction(this.draw); | |
} | |
/* | |
This function will be called when you start drawing | |
*/ | |
onDrawStart = (e) => { | |
//It will store the coordinates length of geometry | |
this.coordinates_length = 0; | |
//partDistanceOverlay is used to display the label of distance measurements on each segment of Line and Polygon geomtry | |
this.partDistanceOverlay = null; | |
//totalAreaDistanceOverlay is used to display the total distance if geomtery is LineString or it will display the area if geomtry is Polygon | |
this.totalAreaDistanceOverlay = new Overlay(this.map).overlay; | |
//lastPartLineOverlay is used to display the distance measurement of last segment of Polygon which is its last two coordinates | |
this.lastPartLineOverlay = new Overlay(this.map).overlay; | |
//Binding onGeomChange function with drawing feature | |
e.feature.getGeometry().on('change', this.onGeomChange); | |
} | |
/* | |
This function will be called when drawing is finished | |
*/ | |
onDrawEnd = (e) => { | |
//Add drawn geometry to vector layer | |
this.vector_layer.getSource().addFeature(e.feature); | |
} | |
/* | |
This function will called when ever there will be a change in geometry like increase in length, area, position, | |
*/ | |
onGeomChange = (e) => { | |
let geomType = e.target.getType(); | |
let coordinates = e.target.getCoordinates(); | |
if(geomType == "Polygon"){ | |
coordinates = e.target.getCoordinates()[0]; | |
} | |
//This logic will check if the new coordinates are added to geometry. If yes, then It will create a overlay for the new segment | |
if (coordinates.length > this.coordinates_length) { | |
this.partDistanceOverlay = new Overlay(this.map).overlay; | |
this.coordinates_length = coordinates.length; | |
} | |
else { | |
this.coordinates_length = coordinates.length; | |
} | |
let partLine = new ol.geom.LineString([coordinates[this.coordinates_length-2], coordinates[this.coordinates_length-1]]); | |
if(geomType == "Polygon") { | |
partLine = new ol.geom.LineString([coordinates[this.coordinates_length-3], coordinates[this.coordinates_length-2]]); | |
} | |
//the calculates the length of a segment and position the overlay at the midpoint of it | |
this.calDistance(this.partDistanceOverlay, partLine.getFlatMidpoint(), partLine.getLength()); | |
//if geometry is LineString and coordinates_length is greater than 2, then calculate the total length of the line and set the position of the overlay at last coordninates | |
if (geomType == "LineString" && this.coordinates_length > 2 && e.target.getLength() > new ol.geom.LineString([coordinates[0], coordinates[1]]).getLength()) { | |
this.calDistance(this.totalAreaDistanceOverlay, coordinates[this.coordinates_length-1], e.target.getLength()); | |
} | |
//If geometry is Polygon, then it will create the overlay for area measurement and last segment of it which is its first and last coordinates. | |
if (geomType == "Polygon" && this.coordinates_length > 3) { | |
this.calArea(this.totalAreaDistanceOverlay, e.target.getFlatInteriorPoint(), e.target.getArea()); | |
partLine = new ol.geom.LineString([coordinates[this.coordinates_length-2], coordinates[this.coordinates_length-1]]); | |
this.calDistance(this.lastPartLineOverlay, partLine.getFlatMidpoint(), partLine.getLength()); | |
} | |
} | |
//Calculates the length of a segment and position the overlay at the midpoint of it. | |
calDistance = (overlay, overlayPosition, distance) => { | |
if(parseInt(distance) == 0) { | |
overlay.setPosition([0,0]); | |
} | |
else { | |
overlay.setPosition(overlayPosition); | |
if (distance >= 1000) { | |
overlay.element.innerHTML = (distance/1000).toFixed(2) + ' km'; | |
} | |
else { | |
overlay.element.innerHTML = distance.toFixed(2) + ' m'; | |
} | |
} | |
} | |
//Calculates the area of Polygon and position the overlay at the center of polygon | |
calArea = (overlay, overlayPosition, area) => { | |
if(parseInt(area) == 0) { | |
overlay.setPosition([0,0]); | |
} | |
else { | |
overlay.setPosition(overlayPosition); | |
if (area >= 10000) { | |
overlay.element.innerHTML = Math.round((area / 1000000) * 100) / 100 + ' km<sup>2<sup>'; | |
} | |
else { | |
overlay.element.innerHTML = Math.round(area * 100) / 100 + ' m<sup>2<sup>'; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment