Limit Google Maps Drawing library to one Polyline/shape - javascript

I have somewhat of a unique problem. I'd like to allow a user to draw only one polyline and limit it to that. I'd also like that to be able to edit the polyline at will. I found this example: Google Maps Drawing Manager limit to 1 polygon but that basically just disables the control panel which still doesn't limit anything and secondly I want them to be able to edit their polyline, just not be able to create new ones.
I'd even be fine if they had some sort of a onDrawStart listener that would clear the previous shape but as far as I can tell, they don't have any such listener. Thanks!

Add a listener to overlaycomplete or polylinecomplete. Save the new layer. Then you can either delete the old one after the user draw another one..
google.maps.event.addListener(map.drawingManager, "overlaycomplete", function(event){
event.overlay.overlayType = event.type;
lastOverlay = event.overlay; // Save it
map.drawingManager.setDrawingMode(null); // Return to 'hand' mode
});
So, if you want to delete the layer => lastOverlay.setMap(null).
There is also a listener that fires when the user select a drawing tool. Mmm I can't find this listener. Not sure if it really exists.

Related

Leaflet with MarkerCluster: How to add/remove markers from cluster at the time of spideriying?

I am working on a Leaflet project, which can have quite a few markers on the map. The behavior that I have currently is, if you click on any of the cluster it will spiderify to show all the marker and the user can hover over individual markers to see more information about it. As the number of markers can be somewhere around 100 - 10K it can be a real issue to show all of them.
Theoretically, I would like to show 9 items and 1 items which will be kind of More marker containing information about the rest of the marker, which can be clicked which would lead to a different page.
My current implementation looks like this on clustermouseover.
private createMarkerClusterGroup() {
if (this.markerClusterGroup) { return; }
this.markerClusterGroup = L.markerClusterGroup(this.effectiveMarkerClusterGroupOptions);
this.markerClusterGroup.on('clusterclick', (event: any) => {
const cluster: ExtendedMarkerCluster = event.layer;
event.layer.spiderfy();
});
Few of the things I have been able to figure out are :-
I can get the total children markers using const markersCount = cluster.getAllChildMarkers();
I will have to remove all the extra markers and set the new markers location equal to any one of the removed markers and set a key with all the id's for them to be retrieved afterwards.
I am unable to put them together and make them work. Any help is appreciated.
I had kind of similar problem once. I resorted to showing a popup containing all of the markers rendered in a list as it was more clear to see. From what I recall I also had to render each marker with a data-id attribute, just to be able to get the data needed for tendering the popup.
Let me know if this helps a bit and don't hesitate to ask for more.

mapBOX - find the element ID on click

Context:
I have my project setup that draws a road on the mapbox as layers (the road is basically a line with styling and painting implemented). Now I need to click an existing line, and wherever I click it, I want to draw a sub-road originating from the point it clicked it
Blue line is Actually line, the surrounding is just styling.
What I want:
I want to get the ID of the line element (or main road), and the point where it is clicked and then when user has clicked on target coordinate on the map, I want to grab that info and add it into existing line so that the line becomes a single with additional breakpoints. This will make the line look like
(the line is single yet it has multiple stops. This makes it consistent. Feels part of line)
The Problem:
I click on the road (the line), and then click somewhere else to stop drawing, I see new road drawn but since it is a separate layer, it looks not consistent with existing one.
Findings:
Every line, every shape is separate layer, since first road, even though it had multiple stops, was in-fact a single road so the design was consistent 3. But since the new line is a new layer, it has its own styling.
I need to find a way to add new data in existing layer
Roadblocks:
Need to find the ID of existing element when I click on it to use it as a source for my new line
Need the pin-point location of click
Need the data for new line/ new layer
find a way to merge into existing layer
Now with all the above context in mind, I am not even able to get the ID of element
SideNote:
While drawing a line in mapbox (using draw.changeMode('draw_line_string'); and then a create various stop points by clicking on map geoJsons) that line stays in one piece even though it has various sub-lines.
Now I need to grab the ID of that line and then specific point when I did click.
Here is my relavent parts of code
draw the line on map
draw.changeMode('draw_line_string');
map.on('draw.create', configureAndUpdateMapBoxDevices);
in configureAndUpdateMapBoxDevices function
draw.add(e.features[0]); //updating event real time for all callbacks where e is passed on as argument so its have these properties.
const json_data = {
json_id: e.features[0].id,
json_string: JSON.stringify(e.features[0])
};
updateMapboxDevice(selected_edit_site_id, json_data); // update on db and models
to style the road defined various variable layers for main road element
map.addLayer(bottomLine);
map.addLayer(left_yellowBelt);
map.addLayer(right_yellowBelt);
map.addLayer(topLayer);
map.addLayer(lineSeparator2L);

Cesium -- on click, change map point to standard marker with icon

I am attempting to mimic the the functionality one would see using the Waze LiveMap (https://www.waze.com/livemap) in Cesium. When a point is clicked, it is converted to a marker with an icon.
I've attempted a few different things with varying levels of success and I'm at my wits end. Does anyone have a good suggestion as to how I can proceed?
There are a couple different ways of doing this, some high-level and some lower-level. The high-level one is easiest so I'll start there. The Cesium Viewer fires an event called selectedEntityChanged when its own selection changes, and you can wire that up to toggle billboard show flags on and off.
Here's a demo. For this demo, I took the original map pins demo and added some lines of code: I turned off the show flags for all the billboards at the start, I added points to stand in for the now-hidden billboards, and I added the following block of code to toggle the billboard show flags when selected, like this:
var lastSelectedPin;
viewer.selectedEntityChanged.addEventListener(function(newEntity) {
if (lastSelectedPin && lastSelectedPin.billboard) {
lastSelectedPin.billboard.show = false;
}
lastSelectedPin = newEntity;
if (lastSelectedPin && lastSelectedPin.billboard) {
lastSelectedPin.billboard.show = true;
}
});
This uses Cesium Viewer's own selection system, but toggles the billboard show flag to appear when selected and disappear when de-selected.
Alternatively, you can dig into Cesium's lower levels for finer control, but there will be a longer learning curve. The Picking Demo shows off several types of picking operations, including scene.pick, scene.drillPick, and camera.pickEllipsoid, which offer various ways to detect what contents exist at a particular screen location. Often these functions are called in response to mouse movements or clicks, or touch/pointer events, to see what the user is interacting with.

setting focus to object on google map

How can I retrieve and object on google map without user interaction. Meaning the user do not click on the object.
I have 10 polygons and I want user to navigate to each of them, manipulate maybe the color.
without clicking on the polygon itself.
I do have a "next" button that when user click, it suppose to navigate to the next polygon setting it active and to be filled with desire color.
The polygons are store in an array with json format.
Im using Data Layer. I am not sure how to implement this. I can click on polygon itself and change the color, but I need to traverse them without clicking.
Thanks
making map:
function loadJson(url, style)
{
var jsonfile = $.getJSON(url).done(function (data){
map.data.addGeoJson(data);
map.data.setStyle(style);
});
}
change color
map.data.addListener('click', function(event) {
mapName.data.overrideStyle(event.feature, currentStyle);
});
WORKING PROTOTYPE
In a data-layer there is no way to access the shapes(e.g. polygons) that have been drawn, you only may access the features.
The problem: the features are not available as array(then it would be easy to iterate over the features or select a feature by index)
Possible solution:
store the polygon-features in an array when they will be added to the layer(could be done via a addfeature-callback)
calculate the bounds of the polygons:(See: How to get LatLngBounds of feature polygon geometry in google maps v3?)
to implement the "next"-feature:
use map.data.revertStyle() to reset the style of the previous selected feature
select the first feature in the array and apply the desired style and call map.fitBounds() based on the calculated bounds(step2)
put the first feature to the end of the array
arrayWithFeatures.push(arrayWithFeatures.shift());
Demo: http://jsfiddle.net/doktormolle/anmfe/

Custom text on map from Mapbox.js

I am using the mapbox js api to draw a few cricles on a map and I would like to add a text to explain what the circle represents. In this case, each circle shows how far you can walk in 5 minutes, 10 minutes and so on.
I want the text to be just a text not a marker (not clickable) but I can't find any way to do this. Does anyone know if this is possible?
Update
To clarify, what I want to do is add a custom text like "New York" in this example https://www.mapbox.com/mapbox.js/example/v1.0.0/marker-popup-onload/
Perhaps you can add a custom legend instead to explain the circles, i.e.:
var map = L.mapbox.map('map', 'examples.map-y7l23tes');
map.legendControl.addLegend('... legend html ...');
you can use custom markers to display whatever you want against a point.
Custom Markers
then just use the following to iterate each layer and open its popup as described in your example. this means you wont have to click on it to open it.
marker.eachLayer(function(m) {
m.openPopup();
});

Categories

Resources