Mapbox - Can't move the marker when location is activated - javascript

mapboxgl.accessToken = 'XXXXXXX';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/satellite-v9', // stylesheet location
center: [ 50.545750,26.050366 ], // starting position [lng, lat]
zoom: 9.5 // starting zoom
});
// TODO: Fix glitch, once location is on the user cannot move the marker
// Allow draggable
var marker = new mapboxgl.Marker({
draggable: true
})
// Add geolocate control to the map.
map.addControl(
new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
})
);
marker.setLngLat([ 50.545750,26.050366]);
function onDragEnd() {
var lngLat = marker.getLngLat();
var lng = lngLat.lng;
var lat = lngLat.lat;
document.getElementById('lng').value = lng;
document.getElementById('lat').value = lat;
}
marker.on('dragend', onDragEnd);
marker.addTo(map);
Hi,
From the code above, everything works the way it's intended however when I activate geolocation then the user cannot move the cursor.
Any help would be appreciated, thanks!

it seems that the z-index for the marker and the geolocation circle wasn't set, so the geolocation kinda overlapped the marker making the user unable to move the marker.
There are a few ways that we can add the z-index to the marker.
1. Get the marker element and add a custom class name with getElement since it's not possible to add className with the mapboxgl.Marker() option at the moment
Your js file
marker.getElement().classList.add("my-marker")
Then in your css
.my-marker {
z-index: 1; // up to you
}
2. Make a custom marker
Your js file
var el = document.createElement("div");
el.className = "my-marker";
var marker = new mapboxgl.Marker(el);
marker.setDraggable(true);
then in your css for example:
.my-marker {
z-index: 1;
background-image: url("https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png");
background-size: cover;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}
hope this could help you!

Related

Google Maps API: How to get draggable map with static pin at centre and get location of this pin each time map is moved

Need to implement a simple draggable map (no zoom), the pin should stay static in the centre, overlaying the map. Every time the map is moved/dragged under the static pin the positioning details of the pin are updated and I can grab those positioning details and display the address in input field above.
Probably a very simple task, I just don't have any experience with Google maps and it would be great if someone could point me either to a working example of this or to right API's/Libraries that I can use in my HTML5/Angular app. Would save me a lot of time researching. Thanks..
You can re-center the marker in a dragend event, and grab the new lat/long. If you want to convert the lat/long to a real world address, you can pass them to a reverse geocoder.
var newlat, newlong;
var latitude = 51.5;
var longitude = -0.12;
var coords = new google.maps.LatLng(latitude, longitude);
var mapOptions = {
zoom: 8,
center: coords,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(
document.getElementById("mapContainer"), mapOptions
);
var marker = new google.maps.Marker({
position: coords,
map: map,
draggable: true,
});
google.maps.event.addListener(map, 'dragend',
function() {
marker.setPosition(map.getCenter());
newlat = marker.getPosition().lat();
newlong = marker.getPosition().lng();
$('#coords').html(newlat + ', ' + newlong);
})
#mapContainer {
width: 400px;
height: 200px;
border: 1px solid #ebebeb;
}
#coords {
width: 380px;
padding: 10px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js"></script>
<div id="mapContainer"></div>
<br>
<div id="coords"></div>

Google Maps API: Want geolocation to click automatically on data layer below

I am trying to build a map-based site that identifies a user's geolocation, draws a marker at his/her position, and then uses that marker/location to click on a data layer (in this case, a GeoJSON layer). Essentially, the user's location should trigger an infowindow automatically if he or she is located on an area delineated by the geojson file. Ideally, each time the user changes location it will be clicking the map to check this GeoJSON layer for info.
So far, I can get the user's location successfully. The map centers on that location. And manual clicks on the GeoJSON layer also populate the info window correctly. But it's not clicking automatically when getting the user location.
I've seen lots of examples where a forced click on a marker takes place, but I can't seem to find one that clicks a data layer. Unfortunately I'm more of a GIS person assigned to a coding job on this, which is way out of my league, so I'm struggling to figure out where I'm going wrong with this.
Here's the script, perhaps I'm making a mistake here:
$<script type="text/javascript">
//centers the map on Iowa City
var map,
currentPositionMarker,
mapCenter = new google.maps.LatLng(41.661354, -91.534729),
map;
function initializeMap()
{
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 18,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.data.loadGeoJson('test2.json');
map.data.setStyle({
strokeColor: '#2687bf',
strokeWeight: 5
});
map.data.addListener('click', function(event) {
document.getElementById('info-box').textContent =
event.feature.getProperty('description');
});
}
function locError(error) {
// the current position could not be located
alert("The current position could not be found!");
}
function setCurrentPosition(pos) {
currentPositionMarker = new google.maps.Marker({
map: map,
draggable: true,
position: new google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
),
title: "Current Position"
});
new google.maps.event.trigger( 'test2.json', 'click' );
map.panTo(new google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
));
}
function displayAndWatch(position) {
// set current position
setCurrentPosition(position);
// watch position
watchCurrentPosition();
}
function watchCurrentPosition() {
var positionTimer = navigator.geolocation.watchPosition(
function (position) {
setMarkerPosition(
currentPositionMarker,
position
);
});
}
function setMarkerPosition(marker, position) {
marker.setPosition(
new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude)
);
}
function initLocationProcedure() {
initializeMap();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(displayAndWatch, locError);
} else {
alert("Your browser does not support the Geolocation API");
}
}
$(document).ready(function() {
initLocationProcedure();
});
</script>
</head>
<body>
<div id="map_canvas" style="height:600px;"></div>
<div id="info-box" style="height:250px;">INFO</div>
</body>
</html>
And here are links to my JSON and full HTML file for this:
https://sites.google.com/site/ecocritkml/coding
The JSON is obviously specific to Iowa City, Iowa, but it could be modified easily in a text editor. Any ideas would be really helpful here.
I think I got it.
I had to use a few tricks (some maybe a little dirty)
I put a 500ms delay with setTimeout; this could have been done more elegantly, no doubt
I make a temporary polygon, because it permits to use containsLocation()
I don't invoke a click, but there is a loop over the polygon features, I read the description there, and set it to the div
..
<!doctype html>
<html lang="en">
<head>
<title>Google maps</title>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src=http://maps.google.com/maps/api/js?v=3&sensor=true&language=en"></script>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map_canvas {
height: 100%;
}
#info-box {
background-color: white;
border: 1px solid black;
bottom: 30px;
height: 20px;
padding: 10px;
position: absolute;
left: 30px;
}
</style>
<script type="text/javascript">
//centers the map on Iowa City
var map,
currentPositionMarker,
mapCenter = new google.maps.LatLng(41.661354, -91.534729),
map;
function initializeMap() {
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 18,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.data.loadGeoJson('test2.json');
map.data.setStyle({
strokeColor: '#2687bf',
strokeWeight: 5
});
map.data.addListener('click', function(event) {
document.getElementById('info-box').textContent = event.feature.getProperty('description');
});
}
function locError(error) {
// the current position could not be located
}
function setCurrentPosition(pos) {
currentPositionMarker = new google.maps.Marker({
map: map,
draggable: true,
position: new google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
),
title: "Current Position"
});
// Wait half a second, then take a loop of the features, see if the marker is inside one of them
setTimeout(function() {
map.data.forEach(function(feature){
var figure = feature.getGeometry();
if(figure.getType() == 'Polygon') {
// make a temporary polygon, see if the marker is inside
var tempPolygon = new google.maps.Polygon({
paths: figure.getAt(0).getArray(), // #see http://stackoverflow.com/questions/33249127/using-containslocation-with-a-google-maps-data-polygon
map: null
});
if(google.maps.geometry.poly.containsLocation(currentPositionMarker.getPosition(), tempPolygon)) {
// marker is inside this feature
// invoke a click. well, just pretend ...
document.getElementById('info-box').textContent = feature.getProperty('description');
}
}
var b;
})
}, 500);
map.panTo(new google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
));
}
function displayAndWatch(position) {
// set current position
setCurrentPosition(position);
// watch position
watchCurrentPosition();
}
function watchCurrentPosition() {
var positionTimer = navigator.geolocation.watchPosition(function (position) {
setMarkerPosition(
currentPositionMarker,
position
);
});
}
function setMarkerPosition(marker, position) {
marker.setPosition(
new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude
)
);
// now we see if the marker is inside one of the polygons
var a = 0;
}
function initLocationProcedure() {
initializeMap();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(displayAndWatch, locError);
}
else {
// alert("Your browser does not support the Geolocation API");
}
}
$(document).ready(function() {
initLocationProcedure();
});
</script>
</head>
<body>
<div id="map_canvas" style="height:600px;"></div>
<div id="info-box" style="height:250px;">INFO</div>
</body>
</html>

Google Maps API - Default marker inaccurate when zoomed out

I am having an issue with the default marker, it seems to be offset when zoomed out. I've had a good look around on here but can only find answers to custom marker images and setting the anchor point on the image. I'm using google's default marker image.
http://thecompleteanimaldirectory.com
This is the website in question, you will notice that the maps in the book will be inaccurate once you zoom out, for example the customer in the Isle of White will end up in Germany!
However, on this page, the maps are accurate.
http://www.thecompleteanimaldirectory.com/search.php?category=dog&area=
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: { lat: 32.00, lng: 15.00},
zoom: 8
};
function initialize() {
var map20 = new google.maps.Map(document.getElementById("map_canvas_barrie"), mapOptions);
function codeAddress20() {
var address20 = "11 Ashey Park, Ashey Road Ryde, I.O.W, PO33 4AL";
geocoder.geocode( { "address": address20}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map20.setCenter(results[0].geometry.location);
var marker20 = new google.maps.Marker({
map: map20,
position: results[0].geometry.location,
});
} else {
map20.setZoom(0);
}
});
}
codeAddress20();
Code is identical for both pages, I have gone as far as to style the maps the same on both pages but no luck. Any help is appreciated!
It's an CSS-issue.
Source of the problem is this rule in main.css, which also applies to images in the map:
.booklet .b-wrap-right img,
#book-right-side img {
position: absolute;
bottom: 10px;
right: 15px;
height: 30px;
}
add this rule to override it:
.right-book .gm-style img{
bottom: 0;
right: 0;
position:relative;
height:auto;
}

Why does the google map api render the map partially 2nd time around?

I have this js code to render my map :
function loadMap(address)
{
console.log(address);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ "address": address }, function (results, status)
{
var pos = new google.maps.LatLng(53.681602, -1.911672); // default.
if (status === google.maps.GeocoderStatus.OK) {
pos = results[0].geometry.location;
} else {
alert("Error : Unable to locate!");
}
console.log(pos);
var mapOptions = {
center: pos,
zoom: 10,
zoomControl: true,
zoomControlOptions: { position: google.maps.ControlPosition.RIGHT_TOP },
mapTypeControl: false,
panControl: false,
scaleControl: false,
streetViewControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions);
var marker = new google.maps.Marker({
map: map,
position: pos,
animation: google.maps.Animation.DROP
});
});
}
Problem is first time it executes the map shows fine, but the 2nd time, the postcode is still the same, the lat/long come out the same yet the map shows partially, with only about a 1/4th of it showing in the top-left of the div.
Anything I am doing incorrectly?
EDIT:
After jterrys suggestions it still looks the same :
HTML/CSS :
#mapCanvas
{
width: 655px;
height: 472px;
border: 1px solid #ccc;
}
<div id="mapCanvas"></div>
I am using JQuery 2.0, I have also had this before when I was using <2.0
Set up the mapoptions and map just once, outside of the geocode callback - then update the marker instead of recreating the entire map.
Fiddle showing one geocode, then another, and back to the first... div positioning looks normal.
Per the updated question, This Fiddle waits for the actual activation of the second tab before rendering the map... I had the exact same issue when creating my tabbed map.
$("#two").click(function() {
init();
}
This could be much more robust and tie into the tabs events that are fired when users interact with them, but this quick example illustrates the solution.
As a side bonus, this also conserves the resources needed to display the map (as well as any quota) until the user actually activates the tab!

Google Maps API v3 controls showing up behind map

greetings & salutations,
this is my first run with the google maps API,
i'm using WordPress and the Genesis Framework,
i'm working through a tutorial on
http://tympanus.net/codrops/2011/04/13/interactive-google-map/
and i've gotten a google map to show up on the map page,
http://www.foodtrucksnashville.com/map/
however, you'll notice the map controls are underneath the map. hmmm.
no idea. need help / nudge in teh right direction.
thx again, stackoverflow community.
here's the code in the init.js:
var map, geocoder, marker, ey, my, mouseDown = false;
var o = {
init: function () {
this.map.init();
},
map: {
size: function () {
// so it's a loverly sqware.
var w = jQuery('.content-sidebar #content').width(),
h = 440;
return {
width: w,
height: h
}
},
data: {
zoom: 13,
center: new google.maps.LatLng(36.165389, -86.783237), // Nashville TN Capitol BLDG
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
init: function () {
// get the map size
var size = o.map.size();
// add some css to the #map div based on the size
jQuery('#map').css({
width: size.width,
height: size.height,
});
// make a new google map in the #map div and pass it the map data
map = new google.maps.Map(document.getElementById('map'), o.map.data), geocoder = new google.maps.Geocoder();
/*
// add eventlistener to map to hide posts when dragging?
google.maps.event.addListener(map, 'dragstart', function () {
jQuery('.posts').hide();
});
*/
}
} // end map
} // end o object
jQuery(window).load(function () {
o.init();
});
My problem came from a z-index on my css file. Tried to disable one by one until I found it.
figure.rounded img {
width: 100%;
z-index: -1; /* Here he is */
position: relative;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
}
finally figured out what as going on,
found the solution over at google groups for the Maps API v3,
http://code.google.com/apis/maps/documentation/javascript/forum.html?place=topic%2Fgoogle-maps-js-api-v3%2F8dOLhjNQzmo%2Fdiscussion
there were some css properties buried in my child theme targeting images with some max-width: 100%.
once i removed all the references targeting img elements with max-width, life was groovy again.

Categories

Resources