I m using draggable markers + 2 autocompletes to get directions.
https://developers.google.com/maps/documentation/javascript/examples/directions-draggable.
I have a listener who catch events when marker has a new position.
google.maps.event.addListener(directionsDisplay, 'directions_changed', function () {
var place1 = autocompleteFrom.getPlace();
var coord1 = [place1.geometry.location.lat(), place1.geometry.location.lng()];
var place2 = autocompleteTo.getPlace();
var coord2 = [place2.geometry.location.lat(), place1.geometry.location.lng()];
});
The problem is autocompleteFrom.getPlace() returns undefined when user has not enter a place in the autocomplete search box.
Is it possible to setup a default location for the autocompletes ?
I am sorry because I don't have enough reputation to comment.
You could set default location for place1, this is more simple than set default for autocompleteform.
Related
I have an issue with a Mapbox map where Popups attached to a Marker are displayed the wrong position, when the map is zoomed out, so we see multiple world copies. See sample below. The Popup are displayed at the correct position when the map is zoomed in and only one world is visible.
This is a simplified version of the code used to add Markers + Popups and display them:
// Add markers to the map
features.forEach(function (marker: any, i: number) {
const popUpContent = '<div>Sample</div>'
// Create the popup
const popup = new mapboxgl.Popup({ offset: 25 })
.setHTML(popUpContent)
.on('open', function (event: any) {
const activePoi = document.getElementsByClassName(poiId)[0]
activePoi.classList.add('active')
})
.on('close', function () {
const activePoi = document.getElementsByClassName(poiId)[0]
if (activePoi) {
activePoi.classList.remove('active')
}
})
let mark = new mapboxgl.Marker(markerElement)
.setLngLat(marker.geometry.coordinates)
.setPopup(popup)
.addTo(map)
})
Question
How can I solve this issue, so that popup appears correctly above their respective Marker, even when multiple world copies are visible?
You can use Mapbox's solution to this: https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/
// When a click event occurs on a feature in the places layer, open a popup at the
// location of the feature, with description HTML from its properties.
map.on('click', 'places', function(e) {
var coordinates = e.features[0].geometry.coordinates.slice();
var description = e.features[0].properties.description;
// Ensure that if the map is zoomed out such that multiple
// copies of the feature are visible, the popup appears
// over the copy being pointed to.
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(description)
.addTo(map);
});
// ...
}
I'm trying to implement a 'filter' feature into my leaflet map alongside marker clusterer, I have got as far as having the control box and plotting the markers however upon unticking a 'category' nothing updates on the map I have attatched an example of which this feature is working http://jsfiddle.net/RogerHN/31v2afte/2/
this is how I plot the marker.
case 'antisocialbehaviour':
marker = L.marker(new L.LatLng(a[0], a[1]), {
icon: icons,
title: 'antisocialbehaviour'
});
markers_cluster.addLayer(marker);
break;
required code for control box ( top of javascript )
var groupA = L.layerGroup(markersA);
var groupB = L.layerGroup(markersB);
var markersA = [];
var markersB = [];
var overlayMaps = {
"A": groupA,
"B": groupB
};
L.control.layers(tileLayer, overlayMaps, {position:'topleft'}).addTo(map);
My code on JSFiddle if anybody needs to see the problem.
https://jsfiddle.net/jgov83fg/25/
I made a copy of your JSFiddle and made some changes to it.
I included the Leaflet.MarkerCluster.LayerSupport sub plugin in the body tag of the JSFiddle's HTML:
<script src="https://unpkg.com/leaflet.markercluster.layersupport#2.0.1/dist/leaflet.markercluster.layersupport.js"></script>
I added the following to the JavaScript code:
var mcgLayerSupportGroup = L.markerClusterGroup.layerSupport(),
group1 = L.layerGroup(),
group2 = L.layerGroup(),
group3 = L.layerGroup(),
group4 = L.layerGroup(),
control = L.control.layers(null, null, {
collapsed: false
}),
i, a, title, marker;
mcgLayerSupportGroup.addTo(mymap);
mcgLayerSupportGroup.checkIn([group1, group2, group3, group4]);
control.addOverlay(group1, 'Anti-Social Behaviour');
control.addOverlay(group2, 'Violent Crime');
control.addOverlay(group3, 'Bicycle Theft');
control.addOverlay(group4, 'Burglary');
control.addTo(mymap);
group1.addTo(mymap); // Adding to map or to AutoMCG are now equivalent.
group2.addTo(mymap);
group3.addTo(mymap);
group4.addTo(mymap);
Then, in the create_marker function, I call either marker.addTo(group1), marker2.addTo(group2), marker3.addTo(group3) or marker4.addTo(group4) based on the type of the crime the marker is associated with.
Hope this helps, let me know if you have any questions.
I've loaded some JSon data outlining each country on a globe as a GeoJSonDataSource into my Cesium project. Each country is also copied as a separate entry into an array. In order to highlight a country, I use
viewer.entities.add(countryArray[countryID]);
which places a colored polygon over the selected country when the user clicks on it. However, when I click on the Camera icon in the info box that Cesium provides by default, nothing happens. In the console, the error message reads:
TypeError: t is undefined
and points to Cesium.js. If I don't add anything to the viewer.entities array, this error doesn't appear.
There may be a better way to highlight the selected country. Try capturing the selected entity, and change the material properties on the existing polygon, rather than creating a new one.
For example, give this a try: Load up the Cesium Sandcastle and paste in the following code into the code editor, then hit F8:
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationHelpButton: false, animation: false, timeline: false,
selectionIndicator: false
});
var deselectColor = Cesium.Color.BLUE.withAlpha(0.3);
var selectedColor = Cesium.Color.LIME.withAlpha(0.5);
var deselectMaterial = new Cesium.ColorMaterialProperty(
new Cesium.ConstantProperty(deselectColor));
var selectedMaterial = new Cesium.ColorMaterialProperty(
new Cesium.ConstantProperty(selectedColor));
viewer.dataSources.add(Cesium.GeoJsonDataSource.load(
'../../SampleData/ne_10m_us_states.topojson', {
stroke: Cesium.Color.WHITE,
fill: deselectColor,
strokeWidth: 2
}));
//Set the camera to a US centered tilted view.
viewer.camera.lookAt(Cesium.Cartesian3.fromDegrees(-98.0, 40.0),
new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0));
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
var previousEntity;
Cesium.knockout.getObservable(viewer, '_selectedEntity').subscribe(function(newEntity) {
if (Cesium.defined(previousEntity) && Cesium.defined(previousEntity.polygon)) {
previousEntity.polygon.material = deselectMaterial;
}
if (Cesium.defined(newEntity) && Cesium.defined(newEntity.polygon)) {
newEntity.polygon.material = selectedMaterial;
}
previousEntity = newEntity;
});
Good Day to everyone, Im developing a site that has a mapping features.
My goal here is make it drag if you click the marker.
Here is my code
else if (select1.value === "Arson"){
var note = document.getElementById('note');
var datepick = document.getElementById('demo1');
var timepick = document.getElementById('timepick');
layerpoly.on('click', function(e){
var markerA = new L.Marker(e.latlng,{icon: Icon1});
markerA.bindPopup("</a><br><strong>ARSON</strong></br><strong>Date:</strong>"+datepick.value+"</br><strong>Time:</strong>"+timepick.value+"</br><strong>Address:</strong>"+note.value+"<strong><br><strong>Suspect Sketch</strong><br><a href=legends/suspect.jpg rel=lightbox><img src = legends/suspect.jpg height=100 width = 100/><br> ").addTo(map);
closure1 (markerA)
var ll = markerA.getLatLng();
document.querySelector('#userLat').value = ll.lat;
document.querySelector('#userLng').value = ll.lng;
marker.dragging.enable();
});
}
The output of the code above is if i select arson. I will place a marker on map.
My question is how can i make it draggable if click that marker?
by the way this code
document.querySelector('#userLat').value = ll.lat;
document.querySelector('#userLng').value = ll.lng;
is connected into two textboxes with id of userLat and useLng. How can i update this textbox if i drag that marker?
Any Help? TY
Here's the documentation for L.Marker: http://leafletjs.com/reference.html#marker As you can see there is absolutely no method called dragging.enable so calling marker.dragging.enable(); will never work and should throw an obvious error to your browserconsole. There is however a draggable option which you can use when you instanciate the marker:
var markerA = new L.Marker(e.latlng,{
icon: Icon1,
draggable: true
});
Here's a working example on Plunker: http://plnkr.co/edit/Au3XlD?p=preview
I am using the Geolocation Marker Script from the Google Maps Utilities Library V3 in order to display the position of a user.
What I want to achieve (I am a newbie to the Google Maps API!) is:
have the users current coordinates displayed (e.g. in a simple CSS container somewhere on the page)
connect an event to a marker. I should be triggered when the user is close.
Appreciate your help!
To display coordinates to the user, you would need a reference to a DOM Element. Then it's a simple matter of updating the content.
HTML On the Page
<div id="UserCoordinates">Waiting on GPS Position ...</div>
In Script
google.maps.event.addListener(GeoMarker, 'position_changed', function() {
var UserPosition = this.getPosition();
var DisplayElement = document.getElementById('UserCoordinates');
if(UserPosition === null) {
DisplayElement.innerHTML = 'Waiting on GPS Position...';
} else {
DisplayElement.innerHTML =
'Current Position: ' + UserPosition.toUrlValue();
}
});
This will show the user their current position as it changes. If you are going to continue using a full screen map, you'll probably want to implement the UserCoordinates div as a map control. The API Reference has a good overview and multiple examples on this.
Display an info window when the user is within X meters of a location
This is a little tricky because there are multiple scenarios to handle and you don't want the infowindow opening repeatedly as they move within your radius.
Distance calculation
I see you have a distance function in your code, but I recommend using the one in the Spherical Geometry library of the API. You just have to specifically load the library with your api script tag:
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=true_or_false">
</script>
Then you need to add to the position_changed event handler:
var IsWithinRadius = false; //assume they start outside of the circle
var RadiusInMeters = 1000; //within 1 km
var LocationOfInterest = map.getCenter();
google.maps.event.addListener(GeoMarker, 'position_changed', function() {
var UserPosition = this.getPosition();
var DisplayElement = document.getElementById('UserCoordinates');
if(UserPosition === null) {
DisplayElement.innerHTML = 'Waiting on GPS Position...';
IsWithinRadius = false; //you don't know where they are
} else {
DisplayElement.innerHTML =
'Current Position: ' + UserPosition.toUrlValue();
var IsCurrentPositionInRadius =
Math.abs(google.maps.geometry.spherical.computeDistanceBetween(
UserPosition, LocationOfInterest)) <= RadiusInMeters;
var JustEnteredRadius = !IsWithinRadius && IsCurrentPositionInRadius;
IsWithinRadius = IsCurrentPositionInRadius;
if(JustEnteredRadius) {
//trigger action here.
alert("Within raidus");
}
}
});