I understand that the minified file from the zip is only the base code, and does not include libraries. Therefore I ran the build.sh file and it produced another minified file that I have included in my scripts.
Expectation:
I am attempting to zoom in on a marker when clicked. I have a function that runs on the event, onMarkerClick.
The problem:
I have looked at (2) different posts:
Jvector map, how to focus on a marker?
https://github.com/bjornd/jvectormap/issues/157
Both posts produce the same exact error.
The error:
Error: <g> attribute transform: Expected number, "scale(NaN) translate(N…". jquery.jvectormap.min.js:733
line 733 - this.rootElement.node.setAttribute('transform', 'scale('+scale+') translate('+transX+', '+transY+')');
Apparently +scale+ is not a number (NaN)
I had a bunch of errors, but finally narrowed it down. First I thought that c had markers[c].latitude and markers[c].longitude, but it did not. Next mistake was not passing the configuration to the setFocus function
onMarkerClick: function (e, c) {
setFocusLatLng(5, markers[c].latLng[0], markers[c].latLng[1]);
}
// sets focus on marker clicked
function setFocusLatLng(scale, lat, lng) {
var mapObj = $('#map').vectorMap('get', 'mapObject');
var config = {
animate: true,
lat: lat,
lng: lng,
scale: scale
}
mapObj.setFocus(config)
}
Update:
In case you ever need to pan back out to full map and set the focus on the center of the map:
// sets focus on center of map and zooms back out to full view
function setFocusMapCenter() {
var mapObj = $('#map').vectorMap('get', 'mapObject'),
center = mapObj.pointToLatLng(mapObj.width / 2, mapObj.height / 2);
var config = {
animate: true,
lat: center.lat,
lng: center.lng,
scale: 1
}
mapObj.setFocus(config)
}
I have fought with this issue today and I'll leave my fix here in case I might help someone.
I was having the same error while trying to focus passing the id like this:
$('#world-map').vectorMap('get', 'mapObject');
map.setFocus(regionId)
But you have to pass an object as written below and it works perfectly. The documentation says it, but it is not that clear, with an example it would work better
$('#world-map').vectorMap('get', 'mapObject');
map.setFocus({region: regionId})
Late to the party but I had this issue myself and these solutions are not the best. Im using jquery-3.5.1.js with jvectormap multimap and it seems to work just fine except this issue occurs if the size of the viewport is changed
The problem is in the file svg-canvas-element.js in the function
jvm.SVGCanvasElement.prototype.applyTransformParams
The solution is to wrapping the setAttribute line with a numeric check on the value for the scale variable.
e.g.)
if($.isNumeric( scale )){
this.rootElement.node.setAttribute('transform', 'scale('+scale+') translate('+transX+', '+transY+')');
}
Make the change, Save, then test by opening the drill-down.html example. The intial map is the United States. Select a region it loads the State map. Now open developer tools ( im doing this in chrome ) then click the back button on the map ( not in the browser ). Now click on a different state it should throw the error in console and the new state may not even appear in the #map1 div if it is still broken. If it is fixed everything will work as expected.
Related
I'm using react to load streetview into a component I get this :
As we can see - the map component loads fine, and the streetview component seems to load fine, except that the image behind it (the actual street view) isn't loaded.
The error reported is :
**
Uncaught TypeError: Cannot read property 'toString' of undefined in
maps.googleapis.com/imagery_viewer.js:299
**
When I run similar code in straight-up HTML, this works ... sometimes ... often I get no returned image
I've isolated the code into a special function triggered with a large setTimeout() call so that the document load time is not to blame. Indeed, using watches and breakbpoints, we can see that the DIVs are loaded and accessible at run time.
handleLoad: ->
options = {
addressControl: true
fullscreenControl: true
panControl: true
pov: this.props.image.pov
visible: true
zoomControl: true
}
if this.props.image.pano
options.pano = this.props.image.pano
else if this.props.image.position
options.position = new google.maps.LatLng this.props.image.position[0], this.props.image.position[1]
if this.props.image.position
pos = new google.maps.LatLng this.props.image.position[0], this.props.image.position[1]
else
pos = {lat: this.props.entryLatitude, lng: this.props.entryLongitude};
options.key ='XXXX - GOOGLE MAP API KEY GOES HERE - XXXX';
this.map = new google.maps.Map(this.mapDiv, { center: pos, zoom: 14, visible:true } , streetViewControl: false);
this.panorama = new google.maps.StreetViewPanorama this.panoramaDiv, options;
this.map.setStreetView(this.panorama);
Any suggestions what could be causing this problem ?
This known black street view panorama issue can be cache or cors related. I suggest you first try ruling both of them out. E.g. see https://support.google.com/maps/thread/6166296?msgid=8836199
It may also be due to a third-party library bug or conflict. E.g. if you're using mootools or prototype.js check out these threads:
Mootools breaks Google maps streetview - black screen
https://issuetracker.google.com/issues/139252493
Another potential reason could be that your lat/lngs are far away from the roads where the street view imagery is available. Have a look at this great answer to related question Google map JS API "StreetViewPanorama" display black screen for some address
Let us know if any of the linked solutions work for you; otherwise please provide a codesandbox or stackblitz that reproduces the issue and I'll be happy to investigate further.
I am building the functionality that allows mapbox markers to be edited from within a CMS. The functionality should open up and populate a form when a map marker is clicked, and then allow the map marker to be dragged. When the form is saved, the content is submitted via ajax and then the map is reloaded with the featureLayer.loadURL("my_geojson_endpoint").
I have added comments throughout my code below to outline how I am getting to the error.
N.B. I define a property db_id in the geojson to identify each point because when you apply a filter, _leaflet_id changes. I also have jquery included in the code.
Code:
// loop through each marker, adding a click handler
$.each(points._layers, function (item) {
var point = points._layers[item];
attachClickHandler(point);
});
function attachClickHandler(point) {
// open the edit state for the marker on click
$(point._icon).on("click", function () {
openEditState(point);
})
}
function openEditState (point) {
disableEditOthers(point);
displayContent(point);
point.dragging.enable(); // this line causes the error
$(point._icon).off("click");
}
function disableEditOthers (point) {
// hide the other markers from the map (using db_id as mentioned above)
points.setFilter(function (f) {
return f.db_id === point.feature.db_id;
})
// this functions as a callback to display the popup
// since applying the filter on click, does not show the popup
setTimeout(function () {
for (key in points._layers) {
points._layers[key].openPopup();
}
}, 0)
}
In the map creation step I have been able to call this dragging.enable() method on each of the markers and provide "draggability" to all of them, however this is undesirable from a usability point of view. I want the user to clear swap in and out of an edit state.
I discovered this issue on github, solved by the solution to this. However after swapping my mapbox.js version out to the standalone and including the latest version of leaflet (0.7.3) the same error still occured.
Am I calling the function on the wrong property of the object? dumping out the "point" variable just before the line which errors does not show that the draggable property has the enable() function defined.
Any help is much appreciated.
Ok so as a slight workaround, but still not solving the original error.
$.each(points._layers, function (item) {
points._layers[item].dragging.enable()
})
Because I have filtered out the other points, enabling dragging on all points is working around the issue.
If you can provide a fix to my original fix (avoiding the loop) I am happy to accept it.
According to the OpenLayers documentation, the constructor, OpenLayers.Map(), allows for an additional property extent which is "The initial extent of the map" (see here).
However, I cannot get it to have any effect. I know I can set an initial extent by calling .zoomToExtent() after constructing the map. But I would like to use this extent property because I set a zoomend event in the eventListeners property but don't want it to trigger with an initial call to .zoomToExtent(). Does anyone have a clue how to use this extent property?
This is the code that isn't working
map = new OpenLayers.Map('map',{
extent: bounds,
layers: [osmLayer,vectorLayer],
projection: "EPSG:900913",
eventListeners: {
zoomend: function() {
//..zoomend event listener code
}
}
});
In the above example:
bounds is a valid OpenLayers.Bounds object
osmLayer and vectorLayer are valid OpenLayers.Layer objects of which osmLayer is the base layer.
What happens with above code is that the map is completely zoomed out (in fact you can't actually see anything) and any attempts to pan results in errors being thrown. To get to map into a correct state the user has to zoom in and then panning works again and you can see the map.
I'm afraid I'm not sure off-handedly how to make the code you listed work, however the following alternative has worked for me:
map = new OpenLayers.Map('map',{projection: new OpenLayers.Projection("EPSG:4326")});
//ADD A BUNCH OF LAYERS AND SUCH HERE
//Set map center to this location at this zoom level
map.setCenter(new OpenLayers.LonLat(-93.9196,45.7326),5);
As a last resort, you could put a line at the beginning of your zoom function:
if(!map_ready) return;
And then set the variable map_ready to true at the appropriate time.
I ran into the same problem.
The "extent" option mentioned in the documentation is there probably by mistake. It does not exist. I checked the source code and could not see any code handling such option. I contacted the author and he already created a pull request for the removal of this option from the documentation.
So I'm trying to use the Search Module of the Bing Maps AJAX API (v7), and I've noticed that in the Interactive SDK for it you can pass in a property called bounds which you give a bounding box to search within. The example simply uses the map's current bounding box so theoretically, if you zoom in, a new search should simply show you results within your zoomed in area, right?
Well here's the issue: Add the following code at the end of the example code in the Interactive SDK:
Microsoft.Maps.Events.addHandler(map, 'viewchange', searchRequest);
What this should do is every time you move around the map or zoom in or out, it should fire a new search with the new bounding area of the map... I say this because of the line that looks like this: bounds: map.getBounds(),. What actually happens is that it bounces back to where it was initially before zooming.
Call me crazy, but is the bounds property just being completely ignored? Does anyone know how to limit the search results to the currently visible map area?
Lastly: Is it just me, or are the API docs for V7 rather incomplete? I've managed to find a few things by inspecting stuff in the Chrome console that doesn't appear in the API docs.
Update: This is what my call to the search function looks like:
searchManager.search({
bounds: map.getBounds(),
callback: searchSuccess,
count: 20,
entityType:"Business",
errorCallback: searchFail,
startIndex: 0,
userData: userData,
what: what,
where: search
});
I have not personally used on view changed as I'm not sure that was available when I migrated from 6.0.
I'll share an alternative route I went that gets the trick done.
My search functionality also puts a Microsoft.Maps.Pushpin exactly where the user searched ("You are here!").
I then I create a boundary from the pushpin:
var viewBoundaries = Microsoft.Maps.LocationRect.fromLocations(pushpin.getLocation());
Then set the Map.setView properties for bounds. (Aswell as zoom in my case)
map.setView({ bounds: viewBoundaries });
map.setView({ zoom: 10 });
If you are not using a pushpin, you can simply create the view boundary from the location class.
MSDN Location Class
I am trying to use the Google Maps V3 API ClusterManager from http://cm.qfox.nl/ to cluster together markers on a map, but I'm hitting the same error in my code as in the original web site - an error when the page is loaded the first time, or reloaded:
Uncaught TypeError: Cannot call method 'fromLatLngToPoint' of undefined ClusterManager_v3.js:586
ClusterManager.latlngToPoint ClusterManager_v3.js:586
ClusterManager._getMarkerBounds ClusterManager_v3.js:645
ClusterManager._cacheMarkerIcon ClusterManager_v3.js:580
ClusterManager.update ClusterManager_v3.js:345
(anonymous function) ClusterManager_v3.js:91
It works fine after the initial load, so I'm fairly sure it's because of a timing issue - e.g., the map or marker isn't initialized before it being used. Unfortunately, I can't figure out a way to wait for everything to initialize because Javascript isn't my first language. Any help or pointers would be most welcome. The source from the web site is the code I'm using almost exactly.
UPDATE:
If found that changing the line:
cm._requestUpdate(50);
to
cm._requestUpdate(250);
Prevented the error. Changing it to 150 resulted in the error occurring 3/10 times. I'm not entirely sure this is a fix, but it maybe so I'm leaving this posted just in case anyone else has a better solution or wants to know mine.
For using Projection methods , it must be initialized. Map will trigger "projection_changed" event, when Projection will be created.Only after that you can use map.getProjection(). So my suggestion is, to add "projection_changed" event's listener, and initialize ClusterManager when it is called:
google.maps.event.addListenerOnce(map, 'projection_changed', function(){
var cm = window.cm = new ClusterManager(
map,
{
objClusterIcon: new google.maps.MarkerImage('markers/cluster.png', false, false, false, new google.maps.Size(20,20)),
objClusterImageSize: new google.maps.Size(20,20)
}
);
// now json contains a list of marker positions. lets add them.
for (var i = 0; i < json.length; ++i) {
.....
}
cm._requestUpdate(50);
});