D3 zoom behavior change in v3 breaking map tile example - javascript

I am building a tiled map based on d3. So I found the corresponding d3 example and copy pasted its code to start my implementation. I need to add overlays to the map so went on and discovered they were misplaced and did not follow the map tiles when zooming. I spent a lot of time bisecting the difference between my adapted copy-paste and the original example and found out this was due to the fact that the example uses v2 of d3 and I am using v3.
My findings is that the main change between v2 and v3 is the behavior of the zoom and translation together. So I tested by zooming and printing the translation vector, and my findings are:
In v2, the projection.translate vector is kept unchanged if the mouse cursor is on the (lat,long) = 0,0) on the initial tile.
In v3, the projection.translate vector is kept unchanged if the mouse cursor is on the top left (most NW point) of the initial tile.
I've made a fiddle in which I copy-pasted the example code, added my debug dots that should cover the earth plus a dot on Paris to see if alignment with the tiles is correct.
You will note that Paris is not correctly placed, (but would be if you run this on d3 v2).
So I guess now there is just some Math to do on my side to update the initial example logic, probably where the tile_origin or tile translation computation.is made. I just started to try to fix them but this seem not trivial. So I am asking here if anybody has an idea of what to change in the example to have it working in v3 (i.e. having a red dot following Paris whatever the zoom level is).
I also could not find any related change in the v3 changelog, if any knows what exactly changed this could help me.

Ok so the best solution is to start from scratch from a v3 example, like http://bl.ocks.org/mbostock/4132797 (which I tried and succeeded with) or http://bl.ocks.org/mbostock/4150951 as Lars Kotthoff commented.

Related

d3 geopath, geojsonlint, CW vs CCW

So this is probably going to be a stupid question and I am missing something obvious, but I've hit a bit of confusion and I'm hoping someone can tell me where I am going wrong.
According to the d3 docs:
Important: the inside of a polygon is all points that the polygon winds around in a clockwise order. If your GeoJSON input has polygons in the wrong winding order, you must reverse them.
Ok, simple enough. However, for every GeoJSON file I've been trying from my project, which lint (via https://geojsonlint.com/) fine, are coming out inverted when trying to display them using d3's geopaths.
So I go to the d3indepth example, which has a nice small GeoJSON example included in it. The example works, and the example data works in my own code. But when I take that example data and run it through the linter, it fails with 'Polygons and MultiPolygons should follow the right-hand rule', and my own 'make sure this is correct' code identifies the polygons as counterclockwise.
Now, the example does seem to match what is listed in RFC7946
A linear ring MUST follow the right-hand rule with respect to the
area it bounds, i.e., exterior rings are counterclockwise, and
holes are clockwise.
So that matches the behavior I see in d3, but not the documentation, and seems at odd with GeoJSONLint.
In trying to figure this out I ran into this earlier question:
d3 v4 geo draws boundary inverted, which provided an even simpler test case. And again, the version that worked in d3 was counterclockwise and failed geojsonlint, while the broken version was clockwise, was inverted in d3, but passed the lint test.
So I guess the basic questions are:
What is correct?
Is the GeoJSONLint website wrong?

Javascript polygon selector, polygon brush

I need a 'polygon' selector type functionality. Basically, the ability to drag lines to form multiple polygons; pref with the ability to edit the 'points' of the polygon after the shape has been 'closed' (but that's secondary) and/or move the polygons...
I generally dislike 'reinventing the wheel' and I figured I'd find tons of examples to work with, but I was wrong...
The polygon tool in Google Maps is just about perfect, but has anyone utilized it outside of GMaps? (I recall it required a GMap as an attribute from my work with Google Maps). Before I roll up my sleeves, I just want to ensure there isn't something already made (this is a very small part) - so if (a) Google Maps Polygon object is usable without a map, or (b) there's another library/project I'm missing please let me know.
Fabricjs is an option you can check.
Have a look at D3.js which has a great api for visualizing data and geo information. Besides the standard one-/two-dimensional brush there are plugins for more advanced types of brushes:
Polybrush. Providing a polygon brush.
lasso. Lassoing a selection by freely drawing a line path.

Median value of heatmap in google maps zoom out

I have a webpage to show some sound values. But when I zoom out, values are added and red zone is bigger that it really is.
You can see an example here: https://developers.google.com/maps/documentation/javascript/heatmaplayer
down side has an example and if you make zoom out, you see the red part bigger.
Is it possible to modify this behaviour to make a median or something similar? It is quite strange that during night, if you zoom out, red zone is so big (meaning that there is too much noise)
The merge rule of Google heatmap is currently density-based. Unfortunately, it still cannot provide a custom merge rule due to its implementation:
Current implementation of heatmap is very perfomance and is computed at client side. The idea is to render each feature as a greyed blur circle. The issue is if two circles overlaps the intersection zone becomes dark greyed because values are added. Later when all features are rendered the class gets an images of the layer, as a grid of pixels, and substitute each grey value pixel (0..255) with a gradient color previously created. (Referenced from Google Forum)
So, maybe you can try the heatmap provided by Nokia. It seems they provide a value-based heatmap, whose merge rule is not defined by density but the value of points.

using cartogram.js for visualizing information in a global map

I'm trying to adapt this example http://prag.ma/code/d3-cartogram/ to show information about obesity in 2002, 2005 and 2010 around the world. This the visualization: http://datauy.github.io/obesity-cartogram with a link to the code in the same page.
The problem I'm trying to resolve is that the shapes are not being distorted like in the original example with the alberusa projection. The colors seems to be mapped just fine but for some reason I can't distort the map. I tried changing the scale and looking into the cartogram.js code but I don't see anything that could be the problem. If I change the data to have a larger difference then I see the color difference but nothing on shape.
Any clue what is happening? Thanks!
The problem is due to Fiji and Russia having project extents which cross the edge and return to the left border. When the cartogram.js calculations complete, the path has a negative value in it which is causing the problem. I'm trying to resolve it myself and will update asap.

How to determine the vertexes for a polygon whose outer edge is a given distance from a line or area in javascript on Google maps?

I have an exercise in problem solving for those who like that kind of thing. I'm working on a mapping application that uses Google Maps. A user first enters a series of coordinates and a "radius". The user then requests either a line or an area be plotted. The plots are taking place on Google Maps using polygons. In other words, given the blue line (or area) defined by the blue points and a distance, calculate the red points and draw the red polygon where the edges are of the given distance away from the user-provided edges:
I have managed to get this to work in "most" situations by calculate forward and reverse bearings, then finding the points with a bearing 90 degrees off these in the appropriate direction. For the arcs I just calculated the location points along that arc at 5 degree intervals. In the case of the inside of an acute angle, I determine where the two lines intersect and use that point, but this fails miserably sometimes when the cross-track distance at that point is greater than the radius that was provided.
I'm hoping someone knows of an easier way? Maybe one that works all the time regardless of the ratio of the cross-track to radius distances? Or maybe a library already exists to do this?
I hope what I'm trying to do makes sense... It's hard to put in words. Maybe if I had the words a search would have been helpful even.
Well, the answer turned out to be simpler than I thought. It took me back to a lesson I was taught during CompSci 101 almost 15 years ago:
"Use existing libraries whenever possible."
Once I found out (via googling), that what I'm looking for isn't called an "offset" or a "scale" but is actually called a "buffer" in GIS computing, it was simple. There are some great libraries like Clipper by Angus Johnson that can do it, but I wanted something JavaScript specific.
That brought me to arcGIS's GeometryService. They even have a Google Maps version but it's only API v2. Luckily, there's an official, unsupported version I found via the arcGIS forums that works with GMaps API v3.
So, my solution was to use that, called arcgislink, and it's buffer function works perfectly with Google Maps LatLng points, Google Maps Polygons/Polylines, and any of the standard arcGIS types. Anyone else needing to do this with Google Maps, I highly recommend looking at their libraries.
In the general setting, this problem is quite difficult because it is a global one (you cannot just solve locally, at each polygon vertex but just handling the two incoming edges). And also uneasy because it involves circular arcs.
There is a solution which is quite unefficient but safe: assume you have a general polygon union algorithm (like http://gvu.gatech.edu/~jarek/graphics/papers/04PolygonBooleansMargalit.pdf); you will add inflated versions of every edge one by one (every time a rectangle and two half-disks approximated by polygons), together with the original polygon for closed shapes.
For the sake of efficiency, you can design a "sweepline" algorithm that works by slicing the plane with horizontal lines at every "event point", i.e. segment/arc endpoints and arc apexes, so that the configuration in every slice is simpler. Do you see what I mean ?
BTW, what do you call the "cross-track distance" ?

Categories