Leaflet: Circle behaving different from CircleMarker - javascript

In the documentation for Leaflet here: http://leafletjs.com/reference-1.2.0.html#circlemarker it says that CircleMaker extends Circle, and that it is the same thing, except the radius is specified in pixels rather than in meters, so that the circles stay constant size even if you zoom the map.
I do however need Circles, because I am trying to draw 100m radius circles on a map. To do this, I use the following code:
var geojsonLayer = new L.GeoJSON(null,{
pointToLayer: function (latlng){
return new L.CircleMarker(latlng, {
radius: 5,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8,
});
}});
map.addLayer(osm);
map.addLayer(geojsonLayer);
geojsonLayer.addGeoJSON(jsonExample);
This works perfectly, however, if I change the code to use "Circle" instead of CircleMaker the entire map fails to load, and I get a javascript error:
Error: Error: Invalid LatLng object: (56.229917, NaN)
I can fix this by pre-filtering the geojson to remove those points which lack both latitude and longitude, but I'm confused: Circle and CircleMaker both specify that they take a LatLng-object as the specification of the center-point, I don't get how a certain LatLng object can be valid as centre-point for a CircleMarker, but invalid if used as the centerpoint for a Circle.
Am I overlooking something obvious, or is this just a weakness and/or bug in Leaflet that I'll just have to work around ?

There is no problem with the code anymore. Though this same issue can arise easily because of the different constructors:
L.CircleMarker( <LatLng> latlng, <Path options> options? )
and
L.Circle( <LatLng> latlng, <Number> radius, <Path options> options? )
Be sure to pass the radius to your new circles.

I fixed this by changing the _getLngRadius() method of leaflet.js in L.circle. In leaflet version 0.4.4, it's around line 4913.
This method differs from the one in circleMarker, as it computes the radius of the circle dynamically. If you change the line that has
this._mRadius/hLength
to
this._mRadius.radius/hLength
it should be ok.

You can add if(latlng && latlng.lat && latlng.lng) at the begining of your function (latlng)
that will ignore the faulty datas.

Related

Google map polygon with outside map tinted [duplicate]

This question already has an answer here:
Google Maps API Polygon with "Hole" In Center
(1 answer)
Closed 7 years ago.
First of all, for the issue you're going to read, I used this snippet of code to highlight my polygon :
Highlight polygon and tint rest of map using Google Maps
Here is my code (it's Angular) :
var boundaries = [];
// big area
var overlay = [
new $rootScope.googleApi.LatLng(80.0, -90.0),
new $rootScope.googleApi.LatLng(-60.0, -90.0),
new $rootScope.googleApi.LatLng(-60.0, 90.0),
new $rootScope.googleApi.LatLng(80.0, 90.0)
];
// my polygon
angular.forEach(settings_boundaries, function(val, key) {
boundaries.push(new $rootScope.googleApi.LatLng(val[1], val[0]));
});
// create a polygon with overlay first
var poly = new $rootScope.googleApi.Polygon({
paths: [overlay, boundaries],
strokeColor: "blue",
strokeWeight: "1",
fillColor: "black",
fillOpacity: 0.4,
clickable: false
});
poly.setMap(interactiveMap);
Now, the real problem is,
If I use these coordinates (which I don't remember how I got them in the first place) :
[[1.6101837158203125,49.00274483644452],
[1.6294097900390625,49.01175312475694],
[1.5947341918945312,48.98787759766659],
[1.6101837158203125,49.00274483644452]]
Everything works fine (as you can see here).
But if I use these ones :
[[1.6809940338134766,48.98337149775796],
[1.6791915893554688,48.96849847697763],
[1.7185020446777344,48.995199140974066],
[1.6809940338134766,48.98337149775796]]
This is not working anymore.
As you can see here.
I used this website to generate the coordinates :
http://www.the-di-lab.com/polygon/ (view screenshot)
I searched for a long time what the issue could be, but I have really no idea. It's approximately the same coordinates. The first lat,lon values are the same than the last ones, for both of them.
If you have any idea (I guess there's something special in the coordinates), I would like to know !
Thanks !
Structurally, the coordinates of the triangle are correct. Only a geometrical difference the first triangle (the one functioning) is drawn in a clockwise direction while the latter is drawn counterclockwise. I have already met a situation like this but I do not remember which site. Then try to reverse the direction of drawing of the triangle in this way:
[[1.6809940338134766,48.98337149775796],
[1.7185020446777344,48.995199140974066]
[1.6791915893554688,48.96849847697763]
[1.6809940338134766,48.98337149775796]]

Add Polygon with array of points

I have a set of markers created around an area and I want to join them together to create a polygon (and shade it). My polygon code:
var polygon = new google.maps.Polygon({
paths: points,
strokeColor: '#f33f00',
fillColor: '#ff99aa',
fillOpacity: 0.2
});
polygon.setMap(map);
Where I have
var points = new Array();
points.push(new google.maps.LatLng(prev_dest.y, prev_dest.x));
Is the .push command no longer working in V3? Previously this worked:
map.addOverlay(new GPolygon(points, "#f33f00", 5, 1, "#ff99aa", 0.2));
Push is simply adding items to the array it has nothing to do with Google Maps API.
For a polygon to know its "closed" - make sure your first and last point in the array of points are the same - otherwise its not a valid polygon.
if its not simply add your fist point again to the array of points.

Leaflet: Are custom zoom levels possible?

Is it possible to have intermediate (2.5, 3.5, 4.5, etc.) zoom levels on a Leaflet map that is using Stamen Toner-lite tiles? This is the code I have so far that calculates the zoom level:
leafletmap.on('zoomstart', function (d){
targetZoom = leafletmap.getZoom(); //Grabs whatever current zoom level is
targetZoom = targetZoom +.5; //Adds .5
leafletmap.setZoom(targetZoom); //Sets new value to zoom level
console.log(targetZoom); //Consoles out new value
});
I tried just adding .5 to the code, but I get a too much recursion error, so I'm guessing it's not that simple. Any help or direction is greatly appreciated!
In version 1.0.0, Leaflet introduced fractional zooming:
https://leafletjs.com/examples/zoom-levels/#fractional-zoom
Before this, the zoom level of the map could be only an integer number
(0, 1, 2, and so on); but now you can use fractional numbers like 1.5
or 1.25.
...
If you set the value of zoomSnap to 0.5, the valid zoom levels of the
map will be 0, 0.5, 1, 1.5, 2, and so on.
If you set a value of 0.1, the valid zoom levels of the map will be 0,
0.1, 0.2, 0.3, 0.4, and so on.
The following example uses a zoomSnap value of 0.25:
var map = L.map('map', {
zoomSnap: 0.25
});
As you can see, Leaflet will only load the tiles for zoom levels 0 or
1, and will scale them as needed.
Leaflet will snap the zoom level to the closest valid one. For
example, if you have zoomSnap: 0.25 and you try to do
map.setZoom(0.8), the zoom will snap back to 0.75. The same happens
with map.fitBounds(bounds), or when ending a pinch-zoom gesture on a
touchscreen.
To be straight to the point: This is not possible. You would need to render your own tile-images, run them of your own server and create your own coordinate reference system (CRS) extension for Leaflet. If you look at how regular tilesets are made you'll understand why.
The URL for requesting tiles for stamen:
http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png
When requesting tiles, the {z} will be replaced with the map's current zoomlevel. The {x} and {y} are the coordinates for the tile. The {s} will be replaced with a subdomain. So if your at zoomlevel 6 at coordinate 1,1 it would try to load:
http://a.tile.stamen.com/toner/6/1/1.png
Now if you could (but you can't) zoom to level 6.5 it would try to load:
http://a.tile.stamen.com/toner/6.5/1/1.png
Those tiles simple don't exists on the stamen server and thus return a 404 for file not found. You can try for yourself just use these links:
http://a.tile.stamen.com/toner/6/1/1.png
http://a.tile.stamen.com/toner/6.5/1/1.png
http://a.tile.stamen.com/toner/7/1/1.png
So that will never work. You could, as said, run your own tile server, render your own tile images and setup your own L.CRS. You might want to take a look at this question too: Adding an extra zoom levels in Leaflet Maps

Colour-coding points on Google Maps

I'm currently developing an application as a page of a college project to display information about house price costs and am looking to implement a colour-coded map for different years. The idea would be that there would be a dot where each house sold was located on a map (Google Maps for example), and colour-coded green to red depending on how expensive it was.
I'm looking for a way to implement this using the Google Maps API, but have been unable to find a solution that doesn't seriously slow up the application as I would be loading in ~30k datapoints for each year and the application currently had 5 years worth of data.
Would anyone have any suggestions on what to use. I've looked at Google's Geocharts and they don't really offer what I am looking for. I've also looked at Heatmaps, and though they get the colouring effect I'm looking for, the points are weighted so the colour is dependent on proximity rather than my specified variable, price.
30K points * 5 years = 150K markers. That might be too much. You should be looking for a way to show only one year of history at a time and/or use marker clustering.
Regarding the color markers, you could use SVG markers for that. You can easily change the color of your SVG path. With a little bit of calculation, you should be able to process all your points and define the color in which to draw the markers.
Example round SVG marker:
var icon = {
path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
fillColor: // your marker color,
fillOpacity: .8,
anchor: new google.maps.Point(0, 0),
strokeWeight: 0
}
var marker = new google.maps.Marker({
position: // your marker position,
map: map,
draggable: false,
icon: icon,
title: 'some title'
});
Here is a quick example:
JSFiddle demo

Creating a circle with Leaflet (using a positive radius)

Making a circle in Leaflet seems pretty straight forward according to the documentation, you just supply coordinates, a radius and optionally an options object:
L.circle( <LatLng> latlng, <Number> radius, <Path options> options? )
I tried doing this on a map I was working on but only managed to produce a dot instead of a circle, no matter how large of a radius I specified. I let this drive me nuts for a while and then stepped away from the code to work on other projects. I recently came back to it and on a whim I tried using a negative value for the radius:
"use strict";
var theMap = L.map("map", {
minZoom: 0,
maxZoom: 7,
crs: L.CRS.Simple
}).setView([0, 0], 0),
eventsLayer = new L.LayerGroup(),
unproject = function (coord) {
return theMap.unproject(coord, theMap.getMaxZoom());
},
coord = unproject([12057.79, 13661.21]),
southWest = unproject([0, 32768]),
northEast = unproject([32768, 0]),
radius = -8653.18, // Why isn't it working with a positive radius?!?!?
circ = L.circle(coord, radius, {color: '#f00', fillColor: '#00f'});
theMap.setMaxBounds(new L.LatLngBounds(southWest, northEast));
L.tileLayer("https://tiles.guildwars2.com/1/1/{z}/{x}/{y}.jpg", {
minZoom: 2,
maxZoom: 7,
continuousWorld: true
}).addTo(theMap);
eventsLayer.addTo(theMap);
theMap.setView(coord, 7, {animate: true});
circ.addTo(eventsLayer);
For some reason it creates a circle with the negative radius.
This seems like a bug since the documentation uses a positive value for radii. Is there something I did wrong in my code that is causing this buggy behavior, or is it possibly a bug in Leaflet?
After coming across this answer I think it is a bug in Leaflet. I downloaded the current version of the dev master and added into the fiddle.
radius = 1,
The new version does accept positive values and makes a circle. It is however buggy in a different way. 0.7 specifies that the radius to a circle should be set in meters. In the current dev version even a value of 1 covers hundreds of meters.

Categories

Resources