Marker Drag and drop event with overlay image calculate pix issue - mapbox

this is an example. I am creating a custom function GetCoordinates this function calculates x and y positions for the image. but this function is not working for your Mapbox init method. can you help me with what can I do this?. Example: "https://jsfiddle.net/ufnvepms/"

Are you trying to get the coordinates of the marker as it is dragged? Or do you want to get the corresponding x/y position of the source image?
The first can be done by adding a listener on the "dragend" event, to get the lat/lon of the marker, as in this example: https://docs.mapbox.com/mapbox-gl-js/example/drag-a-marker/
If you need the second, it would require some more calculation, but before figuring that out wanted to understand more precisely what you're trying to achieve.

Related

How to convert pixels into the map coordinate when calling easeTo() in mapbox

I am developing an interactive map in HTML+JavaScript using mapboxgl (0.33.1). When the user clicks a button (which is associated with a particular location in the map), I call easeTo(), which put that location in the center of the map.
window.map.easeTo({
center: item.loc
});
Because my application has some overlapping UI over the bottom half of the map, I actually want to put that location not in the center of the map, but in the center of the top half of the map (25% from the top).
I'd appreciate if somebody could give me a hint how achieve it. My app knows the exact sizes of the window in Pixel (and also the zoom level), but (I assume) I need to convert it into the map-coordinate (from pixel) to add an appropriate offset to the "center" parameter I pass to easyTo() function.
I think I found the answer. I just need to call the project() method -- which was very hard to discover!

SKTiled: specific tile position

I am using SKTiled.
The SKTileLayer.tileAt(0,0) function returns the tile at a CGPoint.
The SKTileLayer.pointForCoordinate(coord: CGPoint) does the same.
All I want is to get a Tile on the Grid (0,0) and not tiles on CGPoints. That would be the first Grid in the map. How can I get the tiles in that way?
Edit: tileAt(0,0) returns the first Grid but if I want to change the Player position to tileAt(0,0) it ist not the real position.
That's a great framework, you can use the method that returns a tile coordinate for a given point in the layer:
SKTileLayer.coordinateForPoint(<#T##TiledLayerObject#>)
You can find more details to the framework official documentation here
You can also get the tile following the autocompletion as:
As you can see it return a SKTile

Leaflet - tooltips for overlapping polylines

Background:
I am working on a web based mapping application for hiking. So the map based on leaflet offers routes on hiking trails that are labeled. As any hiking trail can be part of multiple routes, routes - respectively the corresponding polylines representing the routes - can overlap.
Problem:
Each route has its tooltip (triggered by mouseover, {sticky:true}) showing its label which works as expected for non-overlapping polylines but as soon as two or more routes overlap only the polyline "on top" gets its tooltip opened. This behaviour is not bad per se but as all routes are equally important I would like to show all labels of the routes at the pointer's location (or something like a maximum of 5 labels + x more). I weren't able to find any issue related to this topic.
What I tried:
- Create a feature group for all routes, bind the tooltip to the group, hoping that the tooltip function provides an array of all polylines crossing the pointer's position. As it turned out, I only get information of the polyline on top
- I tried the same with a mousemove event on the map, no success
- Comparing pointer's layerPoint coordinates with all routes' _rings & _parts layPoint arrays to find matching layerPoints, but the success rate is only about 5% as these layerPoints only cover actual points of the polyline but not the connection between two points. Additionally, there is a margin around each polyline that triggers the tolltip before the pointer even touches the polyline (too improve touch action, I guess)
- A solution to the margin problem is to add positive and negative margins to each polyline point before comparing it to the pointer coordinates which improves the outcome but doesn't solve the main problem.
Sidenote:
- All routes are drawn into a single canvas
Long story short, I need external help to accomplish the goal. Maybe some of you have an idea or can provide a solution. Any input is appreciated.
** UPDATE: **
A working but pretty inefficient solution is as follows
Approach:
Calculate the shortest distance from the pointer to all routes in viewport. If distance from the pointer to a route is under a certain threshold, add them to the array of route labels that should be displayed.
Steps:
1.) bind a blank tooltip to the a feature group containing all routes
2.) bind mousemove event to the feature group with the follwing function
var routesFeatureGroup = L.featureGroup(routesGroup)
.bindTooltip('', {sticky: true})
.on('mousemove', function(e){
var routeLabels = [e.layer.options.label]; // add triggering route's label by default
var mouseCoordAbs = el.$map.project(e.latlng);
$.each(vars.objectsInViewport.routes, function(i, v){
if (e.layer.options.id != el.$routes[i].options.id && el.$routes[i]._pxBounds.contains(e.layerPoint)){
var nearestLatlngOnPolyline = getNearestPolylinePoint(e.latlng, el.$routes[i]);
var polyPointCoordAbs = el.$map.project(nearestLatlngOnPolyline);
var distToMouseX = polyPointCoordAbs.x - mouseCoordAbs.x;
var distToMouseY = polyPointCoordAbs.y - mouseCoordAbs.y;
var distToMouse = Math.sqrt(distToMouseX*distToMouseX + distToMouseY*distToMouseY);
if (distToMouse < 15) {
routeLabels.push(el.$routes[i].options.label);
}
}
})
var routesFeatureGroup.setTooltipContent(routeLabels.join('<br>'));
})
Explanation:
I already gather all objects (routes and markers) in the current viewport for another part of the app. All routes currently visible are stored in vars.objectsInViewport.routes (respectively their ids), so I dont have to go through all routes. The layer that triggered the mousemove event is added by default. I then check for each of the routes currently visible if:
- their id is different to the layer that trigger the mousemove event (as this label is added by default)
- if their bounds (in cartesian coordinates: "_pxBounds") contain the cartesian layerPoint of the mousemove event (for a rough approch to exclude routes that don't intersect)
If these conditions are met for a route, calculate the closest latlng point from the pointer to the route. I do this with a custom function, which is a bit to long to post it in this context. (I will if someone asks for it)
The mouse position and the latlng point on the polyline / route are then converted to absolute coordinates using the map-project method
http://leafletjs.com/reference.html#map-project
At last, the distance between these to points is calculated using pythagoras. It is pixel based, so that the zoom level isn't a factor. If the distance is below a certain threshold (15px) they are close enough to the pointer to be considered as being hovered (with the default margins around a polyline), so the label of the route is added to the label array.
Finally the tooltip for the feature group is filled with all labels.
Results are pretty promising even though the operation is pretty expensive. I added a timeout of 50ms to reduce the function call a bit:
var tooltipTimeout;
var routesFeatureGroup = L.featureGroup(routesGroup)
.bindTooltip('', {sticky: true})
.on('mousemove', function(e){
clearTimeout(tooltipTimeout);
tooltipTimeout = setTimeout(function(){
// collect labels
// ...
},50);
.on('mouseout', function(){
clearTimeout(tooltipTimeout);
})
I can give you an idea of how to do this, but I am not 100% sure that it will do the job. There is a plugin for Leaflet (Mapbox) that can tell you if a point is within a Polygon and it returns all the Polygons that contain that point.
If this plugin doesn't work for polylines you can create a polygon from a polyline by just going back from the last point to the first and closing the line (I am not sure if this suits you solution). For example if you have a polyline of connected points of [0, 1, 2, .... n-1, n] you then go back with connecting [n with n-1, n-1 with n-2, ... 1 with 0]. This way you will have the same shape of the polyline but it will be a polygon. This isn't the most optimized solution, it is a quick fix that uses a known and available plugin.
Once you get all the tooltips, you can open all of them at once for each polygon/polyline. Or maybe open some helper tooltip where the user can select which one he wants to open.
I hope this helps! If you figure out a better solution (or find a plugin that does the job) please post it here.

Create custom map in Leaflet with coordinates

I have a historical city map that I want to display using Leaflet.
I like to set the coordinates of this image to reflect the real world, e.g so I can click on the image and get the real coordinates.
I guess I can just make it an overlay to a real map, but there must be a better solution just define at what coordinates of the corners of the image.
For this image, the approx real world coordinates is NW: 60.34343, 18.43360, SE: 60.33761, 18.44819
My code, so far, is here:
http://stage1876.xn--regrund-80a.se/example3.html
Any ideas how to proceed? It feels like it there should be an easy way to do this?
Any help would be so appreciated!
EDIT: The implementation (so far) with tiles are optional. I could go for a one image-map as well.

How to draw a circle using arcs in createjs?

How to draw an arc in createJS. I have gone through arcTo function but its not what i want. I want to be able to draw several arcs which when put together resembles a circle.
for Ex: I want to be able to draw a circle using 8 arcs. not able to do it using ArcTo function. Please some one suggest me a way to do it.
The arcTo function draws directly from the specified point. The arc() function is what you are looking for.
Here is a quick sample that draws random segments.
http://jsfiddle.net/lannymcnie/nJKHk/
shape.graphics.arc(0,0,50,startAngle,endAngle);
here is another sample with random color fills.
http://jsfiddle.net/lannymcnie/nJKHk/1/