Is Leaflet map setView() inaccurate? - leaflet

In Leaflet map, I'd expect:
map = L.map(...);
...
var latlng1 = L.latLng(-121.99574947357178, 37.33783464876286);
map.setView(latlng1,12, {animate: false});
var latlng2 = map.getCenter();
if (!_.isEqual(latlng1, latlng2)) {
console.log("latlng2 should be the same as latlng1!", latlng2);
}
But in fact, when running this code, latlng2 gets assigned with:
-121.99562072753906, 37.33795407160059
Looks like this is a precision issue, because the coordinates are indeed close.
My question:
I was hoping to use animation with setView:
map.setView(latlng1,12, {animate: true})
As there's no callback which gets invoked when the animation is complete, I was hoping to use getCenter() and _.isEqual (in the moveend event) to compare the requested and actual coordinates.
Since the actual coordinates are not identical, I could write an isCloseEnough() function.
Honestly, I feel my approach is off and so am looking for advice from experienced developers.
Is this a reasonable approach or is there a better solution?

A isCloseEnough is the best option here: the nature of floating point numbers is such that absolute comparisons aren't terribly useful if you do any arithmetic with the numbers in between.

Related

How to bounds in Leaflet?

So ive got a 2000x2000 image as a CRS map where i need to fit -600000 +600000 coordinates, but the image becomes so zoomed that im obviously not doing it right, i guess the program does not know how to combine and calculate that by itself to fit the units into pixels, or does it have a setting for that?
I guess it still makes each pixel of the image approx 600units big but i guess thats accurate enough for what im trying to do.
Coordinates themselves seem to be working as the center of the image is exactly spot on.
var mapOptions = {
center: [11999, 9199],
minZoom: 0,
maxZoom: 0
}
// Creating a map object
var map = L.map('bigmapleaf', {
crs: L.CRS.Simple
}, mapOptions);
var bounds = [[600000,-600000], [-600000,600000]];
var image = L.imageOverlay('../pictures/map.png', bounds).addTo(map);
// Adding layer to the map
map.fitBounds(bounds);
map.setView( center, 1);
Edit:
Now i have managed to find the math that makes the map the right size without any zooming with good precision, but i need to make the map to respond to those kind of large units which i believe requires another conversion back to the original units which does not feel right. I wish i could work with the large units and let leaflet do all the map view conversions. Maybe i try to make a script that discusses both ways with their own units.
Still waiting if someone knows easy answer for my troubles.
In addition to being easier working with them large units, i could also make the map with absolute accuracy.

turf + leaflet, trouble getting positive result from booleanContains/booleanWithin

I've found that intersect works as expected when polygon edges overlap, but I can't seem to identify when one polygon wholly contains another. I created an example here:Stackblitz code example
As expected intersection returns null, but within/contains/overlap all return false. It's a pretty straightforward case, so I'm thinking I must be missing something, given how mature and widely used Turf is. If anyone sees the flaw or has another approach I'd be much obliged. Hit the Compare Features button for the results in the console.
You can use the function contains from leaflet
let contains = this.geoRegion['_layers'][Object.keys(this.geoRegion['_layers'])[1]].getBounds().contains(this.geoRegion['_layers'][Object.keys(this.geoRegion['_layers'])[0]].getBounds());
console.log("Contains",contains);

Is it possible to set a "max allowed pitch" for a Mapbox GL map?

I am unable to find a method to prevent the user from setting the pitch angle of the map too far. I am working with high resolution weather data, so I want to prevent them from setting the pitch so extreme that they can see far away from the intended area. That puts me in a position to either extend the data (WAY too much bandwidth would be used) or just not display it there, making it ugly. I would not like to eliminate the pitch ability completely, as it helps with visualization.
I have looked as much as I can in the documentation but since I cannot find the information and I do not even have a code snippet I have tried because I have nowhere to start. Is there any way to (for example) let the user pitch up to a certain degree only? I made an example image where the left pitch would be OK but not the right, as in that current zoom level it would let them see too far away. If this is not possible, I am open to alternate methods, if any.
Use the render event to check the value of the angle:
map.on('render', (e) => {
if (e.target.getPitch() > MAX_PITCH) e.target.setPitch(MAX_PITCH)
})
[ https://jsfiddle.net/05o4e7dr/ ]
There's now a maxPitch option that you can pass to the Map construct. And, as of Mapbox GL JS 2.0.0, you can set it to pretty high values, all the way up to 85°:
let MAX_PITCH = 85
new mapboxgl
.Map({
container: 'map',
// ...
pitch: MAX_PITCH,
maxPitch: MAX_PITCH,
});

Using leaflet.js with a non-geo map (gdal2tiles.py)

I'm trying to use Leaflet.js to access a non-geo (scanned image ...) map, which I tiled using gdal2tiles.py -p raster. But I absolutely can't get it to work: I see Leaflet requesting URLs with negative coordinates and non-existent ones. (Such as: /3/-1/8.png ...)
The map in question is 1162 pixels wide and 700 pixels high.
The tilemapresource.xml file generated by gdal2tiles says, among other things:
<BoundingBox minx="0.0" miny="-700.0" maxx="1162.0" maxy="0.0"/>
<Origin x="0.0" y="-700.0"/>
So, as you can see, the Y coordinates range from a negative number to zero, and the X range from zero to a positive number. (That's just the way that gdal2tiles.py decided to do it, I guess.)
I am using CRS.Simple like all the documents say to do, and I'm setting the bounds to SouthWest=(-700,0), NorthEast=(0,1162), admitting to be already mightily-confused when I see other examples that seem to be reversing the second (Lng) coordinate.
(I realized that "Lat" corresponds to "Y" and "Lng" to "X.")
Equally puzzling to me is that when I unproject the Southwest and Northeast points using the max-zoom, I get LatLng(-36.3125, -21.875) for SouthWest. I don't know why. (Again, I am using CRS.Simple ...)
Experimentally, I set "tms: false" on the tile-layer, which caused something to show up, but now the display's doing the most amazing thing: entirely on its own, it's "ping-ponging" back and forth along a line from roughly the middle of the right-hand margin down-and-left to the middle of the bottom, and back.
I know I've been whacking at this thing for too long today...
Well, I found it. (And, since I wound up asking this question twice, let me answer it in both places.)
Add all of the layers that you are going to use on your map, when you call the Map object's constructor, using the layers option.
In other words, do not do as I was doing: try to set up the various layers first, then add them to the map. The map needs to know about the layers, and the layers need to know about the map, right from the start. So, add them, then configure them as you need.
Otherwise, "strange and default things may happen." For example, although I specified the Simple CRS, that's not what I effectively wound-up with. It appears that the various objects (map, layers), "talk to one another" quite a bit with this library, and they don't expect to be orphans.
(Some of the "strange things" that can happen are, in fact, bizarre ... like: a tiny version of the map, ping-ponging between "about three o'clock" and "about six o'clock" and back again. A funny and entertaining thing to look at, unless you don't yet know why it's happening, nor how to stop it! Whew! )
The design of "leaflet.js" certainly isn't wrong, to be sure, but it has some unpleasant surprises for the unwary. (Like me.) Hope this helps.

DirectCompute atomic counter

In a compute shader (with Unity) I have a raycast finding intersections with mesh triangles. At some point I would like to return how many intersections are found.
I can clearly see how many intersections there are by marking the pixels, however if I simply increment a global int for every intersection in the compute shader (and return via a buffer), the number I get back makes no sense. I assume this is because I'm creating a race condition.
I see that opengl has "atomic counters" : https://www.opengl.org/wiki/Atomic_Counter, which seem like what I need in this situation. I have had no luck finding such a feature in either the Unity nor the DirectCompute documentation. Is there a good way to do this?
I could create an appendBuffer, but it seems silly as I literally need to return just a single int.
HA! That was easy. I'll leave this here just in-case someone runs into the same problem.
HLSL has a whole set of "interlocked" functions that prevent this sort of thing from happening:
https://msdn.microsoft.com/en-us/library/windows/desktop/ff476334(v=vs.85).aspx
In my case it was:
InterlockedAdd(collisionCount, 1);
To replace
collisionCount++;
And that's it!