Static image positioned far north gets stretched - gis

In our application we have a backend that does some raster processing on a region of a map and sends back an image to the OL-based frontend which inserts the image at the specified extent.
The polygon to process is sent as GeoJSON-coords (EPSG:4326) to the backend which then transforms the polygon to a rectangular projection (EPSG:3035 in this case), does the processing and sends the heatmapped results back to the frontend as a PNG-encoded image, reprojected server-side to EPSG:3857 (to match the projection of our OSM-based background map). The image is then inserted in an ImageLayer using an ImageStatic object, whose extent is computed by the backend (the EPSG:3035-transformed bounding box of the image transformed to EPSG:3857).
This works fine, except for polygons in the far north of Scandinavia. For instance, the image whose extent in EPSG:3857 is [1684632.9133543067,9544855.787615912,2902401.684702249,10831736.048522325] is visualized the following way when added to the map:
The desirable result is for the image to follow the south-eastern boundaries of the shadowed polygon. Instead it is skewed and stretched out to the north-east.
I would be very grateful for any ideas and pointers as to why this is not working as expected.

I solved this by cropping the image to be reprojected as much as possible. The resulting envelope is then much smaller which did away with the distortions. Thanks for hint #Ian!

Related

Drawing svg shapes on top of autodesk viewer, viewer's center coordinate moves when new versions of the same drawing are uploaded

We have a web application where we let the users draw SVG shapes on top of the Autodesk Viewer. We can translate the on-screen coordinates to the drawing using the worldToClient and the clientToWorld functions and it works beautifully, the shapes scale and move around with the drawing.
We also let the users update update the drawing by uploading new versions of it, and this has turned into a problem where the center coordinate (0,0) will change when the drawing has changed. That means that the SVG shapes will have the wrong positions when used with the new version of the drawing. It seems to me like somewhere in the translation the original positions of the .dwg files are ignored and a new center coordinate is computed from the content.
Our current workaround is for the users to draw a square frame around the drawings that they wish to use in this way. If all changes happen within that square the center will not move with new versions.
Does anyone have any thoughts, ideas, or experiences on how to solve this without the users needing to edit the drawings?
When using viewer.clientToWorld and viewer.worldToClient with 2D drawings, the "world" typically means page dimensions. In your case, the two DXF files you provided had the same page dimensions, and the content in each DXF file was scaled to fit the entire page. That's why the "world" coordinates between the two DXF files didn't match.
Luckily, when converting DXF files, the Forge Model Derivative service also exports the "source to logical" transformation which I believe defines the conversion from the original coordinates to the page coordinates. When you compute the inverse of that transformation, you should be able to convert from page coordinates back to the source coordinates, and those are the ones you should store with your markups. The conversion into the source coordinates might look something like this:
const res = viewer.clientToWorld(ev.clientX, ev.clientY);
if (res && res.point) {
console.log('page coords', res.point);
const sourceToLogicalXform = viewer.model.getData().metadata?.page_dimensions?.source_to_logical_xform;
if (sourceToLogicalXform) {
const sourceToLogical = new THREE.Matrix4().fromArray(sourceToLogicalXform).transpose();
const logicalToSource = new THREE.Matrix4().getInverse(sourceToLogical);
console.log('source coords', res.point.clone().applyMatrix4(logicalToSource));
}
}

How to add a background image to google maps markers?

I'm using foursquare API to show some places on a map. When I tried to render the icons in the categories some images give 404. Ex:
https://foursquare.com/img/categories_v2/shops/mall.png
So I change the pattern to match this path that is the path that foursquare uses for it's icons:
https://foursquare.com/img/categories_v2/shops/mall_32.png
The problem now is that these icons have transparent background (which looks confusing) and I want to know a way to attach these markers some kind of background.
Thanks!
PD: I don't want to use shadows because I read it's deprecated.
Google map markers are put in place as Canvas elements not DOM elements, and there's no direct equivalent of a background image.
You could try one of two things :
Create your own marker image complete with a halo or background rectangle, then specify your image as the icon when marker(s) are created (see the marker options section of the documentation).
Create a general purpose background image with no foreground then, for each required marker create two markers positioned such that the foreground overlays the background.
The first approach is more efficient and would generally be preferred.
The second approach might be useful if you had many types of marker and wanted each of them to be set against the same background image. This would be inefficient in terms of client CPU and RAM but would save you time in preparing the artwork.

Google Map API v3 Color Customization

I am trying achieve a map like the above image using google map. I made the map grayscale by giving saturation to -100 in StyledMapType object and drawn a radius around the marker using Circle object. Now the whole map is grayscle as i cannot set another saturation level inside the circle. Is there any way to achieve this ?
Another idea is to create second map, style it in another way via StyledMapType, make it absolutely positioned, and put it in front of first grayscaled map.
You can make it look round using -webkit-mask like described here
You should also synchronize events between maps, so that they would coincide, i.e. centered to the same position and always have same zoom level.
You need also to create some kind of blocker to avoid recursive calls
var block = false;
google.maps.event.addListener (thismap, 'center_changed', function(event) {
if (block) return;
block = true;
othermap.setCenter(thisMap.getCenter());
block=false;
});
The same should be done for 'center_changed' (to control maps centering) and for 'zoom_changed' (control maps zoom), for both maps
Here I've set up an example
If you will need to create more than one map that way, you'll need to do more work to make them stick to necessary points
As far as I am aware there is no way to accomplish this directly within the API. I have had to achieve a similar effect in the past and the way that I went about it was to create a 'donut' rather than a circle.
Effectively the idea is to create a large shape which excludes a circular area at it's center. This way you can set the opacity on the polygon fairly low in order to highlight the 'area of interest' in this case the central circle.
This is perhaps a good starting point: http://www.geocodezip.com/v3_polygon_example_donut.html
Though obviously in your case your going to want to alter the colors. Also be aware that the size is fixed so unless you limit the map bounds users will be able to zoom out far enough to see the edges (thus ruining the illusion), and polygons distort towards the poles (pesky spherical earth).
Hope this helps.

Around-the-world path breaking in Google Static Maps

I'm creating Google Static Maps with a path between markers and have come across certain coordinate combinations that break the path.
The path breaks in this example (markers # Beijing, SF, NY, Azores, Rome):
http://maps.google.com/maps/api/staticmap?path=color:0xff0000cc|weight:3|39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577|41.89052,12.494249&markers=39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577|41.89052,12.494249&maptype=terrain&sensor=false&size=640x404
And works in this example (marker # Rome removed)
http://maps.google.com/maps/api/staticmap?path=color:0xff0000cc|weight:3|39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577&markers=39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577&maptype=terrain&sensor=false&size=640x404
The cause is not crossing over the Greenwich Meridian as I initially thought. It breaks even if I add a marker before that, seemingly any a point East of the automatically calculated centerpoint of the map...but only when the path starts on the other side of -180 longitude.
To prove that, you can see that the Beijing, SF, NY, Azores, Rome path displays correctly when I set the map centerpoint to -170,35
http://maps.google.com/maps/api/staticmap?path=color:0xff0000cc|weight:3|39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577|41.89052,12.494249&markers=39.904214,116.407413|37.77493,-122.419416|40.714353,-74.005973|38.721642,-27.220577|41.89052,12.494249&maptype=terrain&sensor=false&size=640x404&center=-170,35
Unfortunately, I can't programmatically set center like this because I never know the collection of points I'm going to get, and it would be next to impossible to detect that the passed points would cause a line break.
Any ideas?
First: you can calculate the center even if you don't know the collection of points (locations) at compile time: at runtime you know all the points (otherwise it would be not possible to insert the coordinates into the URL), therefore you can easily iterate over all the points and compute the center. You can computing the average of all coordinates and you get the geometric center (also called centroid): this is the easier way. Another way to do is to check the most distant pair of locations (for both, latitude and longitude) and then set the middle point as center: this requires slightly more coding (for instance to compute the longitude distance you need to take into account the you have to compute the distance in two directions, since it is possible to go 'around the world) and it has an higher complexity.
I don't go deeper in this topic because, even if you compute correctly the center of your points, this does NOT resolve the problem, and moreover the center provided automatically by the Google static map API is always correct: again the center is related to the problem, but it is not the (couse of the) problem.
An aspect that is trivial but important to keep in mind: Google static map draws a path between two locations always by considering the shortest path, i.e. by drawing the shortest straight line.
Therefore if you are in a situation where your path has to go from a location A to a location B, and the shortest path between A and B goes 'around the world' (or better, it goes out from one side of the image), then the path appears 'borken' as in maps that you have shown. In practice A and B are near the left and right margins of the map, and the map can not be centered in some point along the shortest path between A and B because of the others point of the path. And this is what happen when you remove 'Rome': without Rome the map can be centered in a way that the path is not borken.
Formally, I think that the problem appears (i.e. the path is broken), when the projection of the path on the equator is longer than 360 degree of longitudes, and the path always goes in the same direction (i.e. always west to east or always east to west).
Google static map in this situation simply adds another world map next to the first one: if you set the zoom to the minimum, you can see up to three world maps. This is really impractical for several reasons:
you can not zoom out infinitely;
if you want also insert markers into the map they will be drawn only on the 'main' map;
potentially you can have a path that goes around the world (passing in sequence from America, Europe, Asia, and America again and so on...) many times, and it would be really terrible to have so many little maps one after each other;
I googled a lot about this problem, and I didn't find any solution, there is a bug open on the bug tracker, but it is unsolved.
In my opinion the 'right' way to do is simply the following: at most one map and if a path has to goes out from one margin of the map/image, then it should appear on the opposite margin and continues to the destination, drawn on the same map.
So I found a first workaround:
you draw your path, and with the same style (line's color, etc) you also draw the path in a reversed way (Google static map allows to draws multiple paths in the same map), i.e. path=A|B|C&path=C|B|A and this will solve the problem in many situations (i.e. the path exits from one side of the image and enters from the other). Unfortunately this not works always: if you have a path that cross the image margin two consecutive times, then you lose a portion of your path
To solve this problem I found a second workaround:
- not draw simply the path and its reverse, but draw a different path for every pair of locations of the path (and reversed), i.e. for a path A->B->C then: path:A|B,path=B|C,path=C|B,path=B|A and this works always
The drawback is that in this way the URL becomes very long and the limit of 2048 characters for URLs is easily reached.
The best solution would be to compute manually the center, check manually where the path will cross the margin, and only for this portion of the path draw an additional path going between the two locations at the margin (and maybe also the reverse), but I do not think it really worth, although I do not think Google ever will solve this problem.

Can I draw lines on top of an "gif" image using the <canvas> function?

I'm having difficulty drawing lines on top of an uploaded "map.gif" image.
Basically I've upload a small outline map and use the "area" function to create defined areas (cities, roads, etc). When I click on a city a snall pop up gets displayed with the word "hey, you've just click on Dallas" (or where ever). All that works just fine.
My problem is that my map is actually just a blank outline with no actual cities or roads drawn on it.
Therefore I tried using the "canvas" function to draw the cities (circles) and roads (lines).
The only problem is that they appear below the map rather than on top of it.
Any ideas as to how I can get the lines to appear on the map?
Many thanks,
Pete
You might just have to try playing with the CSS z-index values of the image and canvas.
Do make sure you set the canvas to be transparent.
An other possibility is to replace the image with the canvas (or just load the image in the canvas to begin with).
For some hints on how to use images with canvas take a look here.
I would load the gif directly in the canvas memory, and then do all the rest inside the canvas itself.
The gif is not animated, right?
Some reference about loading: https://developer.mozilla.org/en/Canvas_tutorial/Using_images