Circle not showing in OpenLayers - coffeescript

Extremely new to OpenLayers and trying to draw a circle on a map around a clicked origin. I have this code -
circleLayer = new OpenLayers.Layer.Vector "Circle Search"
circle = new OpenLayers.Geometry.Polygon.createRegularPolygon(
new OpenLayers.Geometry.Point(lat,lon),
100,
30
)
console.log(circle)
feature = new OpenLayers.Feature.Vector(circle)
circleLayer.addFeatures(feature)
mapApp.map.openLayersMap.addLayer circleLayer
But the circle is not showing up, and I'm not sure why. Can anyone tell me?

Are you converting your lat lon to the projection used by your map?
Test:
Try using 0,0 for lon,lat with a bigger circle and see if it appears off the coast of east-central Africa.
If that's the problem then here's how you do the transform:
add at the top:
projLatLon = new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
projMap = new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator Projection
then the third line of your example code becomes:
new OpenLayers.Geometry.Point(lat,lon).transform(projLatLon,projMap),

Related

How to change the map center position to top place using Leaflet open street map in angular

In my angular application I have created the leaflet map and over the leaflet map I have created two more panels data in overlapping manner And I have created the circle of 5 km radius on the map. But my problem is the panels are covering the circle on the leaflet map
So my requirement is to move the center position of the map i.e circle to top position(top middle) than only the circle will be visible otherwise it will be covered by the panels on the map.
component.ts
map = L.map('map').setView([13.0827, 80.2707], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
L.control.zoom({
position: 'bottomright',
}).addTo(map);
I am new to leaflet map Can anyone help me regarding this.
You can let the map fit the circle bounds, like:
var circle = L.circle() // Your circle
map.fitBounds(circle.getBounds())
To show the circle on the left side of the map:
map.setView(circle.getLatLng(),map.getZoom(),{animate: false})
sw = map.getBounds().getSouthWest();
psw = map.latLngToContainerPoint(sw);
center = map.getCenter();
pc = map.latLngToContainerPoint(center);
dis = pc.x - psw.x;
middle = dis / 2
pnewCenter = L.point(pc.x+middle,pc.y)
center2 = map.containerPointToLatLng(pnewCenter);
map.setView(center2,map.getZoom(),{animate: true})

How to get the edge of a polygon drawn on map within Leaflet

I am working with Leaflet and Leaflet-Draw in Angular to draw some polygons on the Google Map. How can I implement a listener when the user clicks exactly on the edge of the drawn polygons and get the lat and lng of that edge. I know a similar situation can be implemented with Google Map API like the code below, but I can not find any source to help me implement the same thing in Leaflet.
google.maps.event.addListener(polygon, 'click', function (event) { console.log(event.edge) }
Google Map Documentation: https://developers.google.com/maps/documentation/javascript/reference/polygon#PolyMouseEvent
For those who come across this question: I found a solution myself!
I didn't find anything directly from Leaflet draw library that I could use, so I defined the problem for myself as a trigonometry problem and solve it that way.
I defined a function in which on polygon click, it converts the event.latlng and loops over polygon.getLatLngs()[0] taking a pair of A and B points. A is the first coordinates, B is the next and if it reaches to the end of array, B will be the first point. Then using Collinear Function of 3 points with x, y, I checked if the clicked x, y has a same slope as point A and B.(has to be rounded it up), if so, I would save that A and B point pair with their latLng information and further used it in my project.
Although this method works, I would appreciate if anybody would know a better solution or library built-in function that can be used instead. Thanks!
When the user clicks on the polygon you can loop through all corners and check if he clicked in the near of the corner.
poly.on('click', function(e){
var latlng = e.latlng;
var corners = poly.getLatLngs();
if(!L.LineUtil.isFlat(corners)){ //Convert to a flat array
corners = corners[0];
}
//Convert the point to pixels
var point = mymap.latLngToContainerPoint(latlng);
//Loop through each corner
corners.forEach(function(ll){
//Convert the point to pixels
var point1 = mymap.latLngToContainerPoint(ll);
var distance = Math.sqrt(Math.pow(point1.x - point.x, 2) + Math.pow(point.y - point1.y, 2));
//Check if distance between pixels is smaller then 10
if(distance < 10){
console.log('corner clicked');
}
});
});
This is plain JS you have to convert it self to angular.
A alternativ is to place on each corner a DivMarker or a CircleMarker and fire a event if the marker is clicked.
Looks like: https://geoman.io/leaflet-geoman

Easeljs: Object added to stage on click has no X value

Trying to following the example at http://www.createjs.com/tutorials/Mouse%20Interaction/ , which shows how to drag and drop a shape. Something is going wrong for me. I add a circle when the stage is clicked, then I try to get it's x location... my alert shows a 0, but the circle appears in the right place. Then I try to drag, and the circle moves around, but at a distance from the mouse pointer.
var stage = new createjs.Stage("demoCanvas")
stage.on("stagemousedown", function(evt) {
var corn = new createjs.Shape()
corn.graphics.beginFill('white').drawCircle(evt.stageX, evt.stageY, 20).endFill()
stage.addChild(corn)
stage.update()
alert(corn.x)
corn.on("pressmove", function(dragEvent) {
dragEvent.target.x = dragEvent.stageX;
dragEvent.target.y = dragEvent.stageY;
stage.update()
});
})
You are mistaking the shape x/y position with the graphics coordinates. The shape is at [0,0], since you have not changed its x or y position.
Instead, draw the circle at [0,0], and move it to the mouse position.
var corn = new createjs.Shape()
.set({x:evt.stageX, y:evt.stageY});
corn.graphics.beginFill('green').drawCircle(0,0,20).endFill();
Here is a quick fiddle: http://jsfiddle.net/xnn803sx/

leaflet editable restrict draw to a specific area

In Leaflet.Editable I want to confine/limit my customers to draw only in a specific area/bounds.
actually im trying to limit them to (90, -90, 180, -180) bounds of map..
maxBounds: [[-90, -180], [90, 180]]
I was not able to find anything anywhere and it seems that i am missing something.
CODEPEN DEMO
please help.
EDIT:
the Y axis is blocking correctly and mouse cannot stretch shape beyond top and bottom.
the problem is in X axis (as seen in pictures)
as for now i solved it with after save check and clear shape if it out of map bounds (BAD USER EXPERIENCE). i need a mouse confinement just like y axis does.
Without knowing your use case (why the whole world map??) Quickest and easiest fix would be to simply set the map's minZoom to something a bit higher, for example, I found that minZoom: 5 was adequate except for cases where the map was both really short and really wide (which is rarely the case in most apps I've seen).
But the real fix involves writing your own custom overrides for dragging markers and shapes.
According to API doc the L.Editable plugin allows you to override a bunch of stuff including the VertexMarker class, via map.editTools.options.vertexMarkerClass.
Fixed codepen: http://codepen.io/anon/pen/GrPpRY?editors=0010
This snippet of code that allows you to constrain the longitude for dragging vertex markers by correcting values under -180 and over 180 is this:
// create custom vertex marker editor
var vertexMarkerClass = L.Editable.VertexMarker.extend({
onDrag: function(e) {
e.vertex = this;
var iconPos = L.DomUtil.getPosition(this._icon),
latlng = this._map.layerPointToLatLng(iconPos);
// fix out of range vertex
if (latlng.lng < -180) {
e.latlng.lng = latlng.lng = -180;
this.setLatLng(latlng);
}
if (latlng.lng > 180) {
e.latlng.lng = latlng.lng = 180;
this.setLatLng(latlng);
}
this.editor.onVertexMarkerDrag(e);
this.latlng.update(latlng);
this._latlng = this.latlng; // Push back to Leaflet our reference.
this.editor.refresh();
if (this.middleMarker) this.middleMarker.updateLatLng();
var next = this.getNext();
if (next && next.middleMarker) next.middleMarker.updateLatLng();
}
});
// attach custom editor
map.editTools.options.vertexMarkerClass = vertexMarkerClass;
I didn't code for dragging the shape as a whole (the rectangle, in this case). While the VertexMarker fix should address all kinds of vertex dragging, you need to override each shape's drag handler to properly constrain the bounds. And if bounds are exceeded, crop the shape appropriately. As was pointed out, Leaflet already does this for latitude, but because Leaflet allows wrapping the map around horizontally you have your essential problem. Using rec.on("drag") to correct the bounds when they cross over your min/max longitude is the only way to address it. It is basically the same solution as I have laid out for the vertexMarkerClass - actual code left as exercise for the diligent reader.

Leaflet - draw polyline vertices only

The title is quite clear, I'm using Leaflet and I need to show only the vertices of a polyline. For exemple see this image :
Currently I can only have the black line, I'd like only the red squares. Using markers is not an option for performance issue, my lines can be huge (500 000 vertices) and the use of smoothFactor is a need.
Is that possible? If not, does someone knows a plugin that does that, or have a hint on how could I do that by extending the Polyline class?
What you could do here is every time the polyline gets rendered, get the segments of it's SVG path, use those points to add SVG rectangle elements to the polyline's container:
var polyline = L.Polyline([]).addTo(map),
list = polyline._path.pathSegList
// Iterate segments
for (var i = 0; i < list.length; i++) {
// Create SVG rectangle element
rectangle = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
// Set rectangle size attributes
rectangle.setAttributeNS(null, 'height', 4)
rectangle.setAttributeNS(null, 'width', 4)
// Set position attributes, compensate for size
rectangle.setAttributeNS(null, 'x', list[i].x - 2)
rectangle.setAttributeNS(null, 'y', list[i].y - 2)
// Set rectangle color
rectangle.setAttributeNS(null, 'fill', 'red')
// Append rectangle to polyline container
polyline._container.appendChild(rectangle)
}
Seems to work as far as i had time to test it ;) Had to use a timeout though, don't know why, look in to that when i've got more time on my hands.
Example on Plunker: http://embed.plnkr.co/vZI7aC/preview