I'm having an issue where my KML Layer does not appear on an embedded google map on my website.
I made a free website using google sites and uploaded my KML file to it so that I could set the url: 'https://sites.google.com/site/kmlroute/home/kml'. The google map itself shows up but the KML layer at that url does not.
My code is below. Does anyone see any syntax errors, logic errors, or anything of the sort that would be stopping my KML Layer from appear on my map???
Any comments, help, and advice is welcome and sincerely appreciated.
function initMap(lat, lng) {
var myLatLng = {lat: lat, lng: lng};
// Create a map object and specify the DOM element for display.
var map = new google.maps.Map(document.getElementById('bus_1_map'), {
center: myLatLng,
scrollwheel: false,
zoom: 12
});
var route = new google.maps.KmlLayer({
url: 'https://sites.google.com/site/kmlroute/home/kml',
map: map
});
You need to pass the URL of the XML file itself.
Try this:
var route = new google.maps.KmlLayer({
url: 'https://sites.google.com/site/kmlroute/home/kml/Bus%2022%20Route.kml.xml?attredirects=0&d=1',
map: map
});
How did I the url?
Go to https://sites.google.com/site/kmlroute/home/kml
Copy link address of the download arrow.
Related
I'm trying to implement my own shape class with ports. However I want the links that these shapes generate to be smooth. Right now, the only way i know to make smooth links is
link.set('smooth', true).
But how do i do that not through code? How do i get smooth links by just dragging?
I extended Link class (MyLink) but how do i tell JointJS which Link class to use when i drag on the port?
joint.shapes.myclass.Link = joint.dia.Link.extend({
defaults: {
type: 'myclass.Link',
attrs: { '.connection' : { 'stroke-width' : 5 }},
smooth:true
}
});
Links created via the UI by dragging ports are defined in the defaultLink property of the paper. It can either be an object in which case it is a link model or a function that returns a link model:
var paper = new joint.dia.Paper({
defaultLink: new joint.shapes.myclass.Link,
...
})
or:
var paper = new joint.dia.Paper({
defaultLink: function(elementView, magnet) {
if (aCondition) return new joint.dia.Link;
else return joint.shapes.myclass.Link;
}
})
The function gives you flexibility in creating different links on the fly depending on what element is underneath or what magnet (SVG element for port) is being dragged.
I'm using the plugin Leaflet.Control.Search to search markers in a layer group, which works fine. Once the marker has been found, the map already automatically pans to the center of the respective location, and the marker popup is being opened.
Now, on search, I would like to set the map's zoom level to a fixed value.
My map's initial zoom level is 12 – but once someone uses the search i'd like to set it to 16. How could this be achieved? I tried to implement setZoom, but I'm not sure how the correct syntax should be..
The code looks like this at the moment:
var searchControl = new L.Control.Search({layer: markers2, propertyName: 'Name', circleLocation:true});
searchControl.on('search_locationfound', function(e) {
e.layer.openPopup().openOn(map);
map.setZoom(16);
});
map.addControl( searchControl );
Thanks a lot for any hints!
ps: when i put map.setZoom(16); BEFORE e.layer.openPopup().openOn(map); then the zoom works fine, but the popup doesn't open like it should – it only opens when I hit search again…
Have you tried map.setZoom(16);instead of this in your "on location found" listener?
Alternatively, you might want to try the map.setView(). It takes a lat/lng and zoom level. You can either take in the marker's lat/lng or the popup's lat/lng
Try editing the plugin, commenting the zoom option (line 26)
_config: {
country: '',
searchLabel: 'buscar en el mapa...',
notFoundMessage: 'destino no hallado',
messageHideDelay: 3000,
/*zoomLevel: 18*/
},
I did it another way.
After the
propertyName
I put
zoom: 16
The code looks like this:
var searchControl = new L.Control.Search({
layer: allLayers,
propertyName: 'myKey',
zoom: 16
}).addTo(map);
I'm using the wonderful plugin Leaflet.Control.Search in order to search for markers (from a geoJson marker group) on my map – which works great.
I only have one simple question now:
how can I open a popup for the search result marker?
I'm using custom marker icons with popups (which open on click) already bound to them – but I would like to open the respective popup automatically once it has been found via the search.
My code looks like this:
var searchControl = new L.Control.Search({layer: markers2, propertyName: 'Name', circleLocation:true});
searchControl.on('search_locationfound', function(e) {
e.layer.bindPopup(feature.properties.Name).openPopup();
}).on('search_collapsed', function(e) {
markers2.resetStyle(layer);
});
map.addControl( searchControl ); //inizialize search control
and thought it might work with that line:
e.layer.bindPopup(feature.properties.Name).openPopup();
but unfortunately it doesn't.. ;)
–
Oh, and a second question: at the moment I'm searching only in 1 geoJson layer ("markers2") – does anyone know whether it's possible to search in multiple layers at once?
Any suggestions? I'd be grateful for any help, thanks in advance!
got it: it works like this: e.layer.openPopup().openOn(map);
event.layer is set only for preloaded layer, if you search marker by ajax,jsonp or callData.. event.layer is undefined.
var geojsonLayer = new L.GeoJSON(data, {
onEachFeature: function(feature, marker) {
marker.bindPopup(feature.properties.name);
}
});
map.addLayer(geojsonLayer);
var controlSearch = new L.Control.Search({layer: geojsonLayer, initial: false});
controlSearch.on('search_locationfound', function(event) {
event.layer.openPopup();
});
Look at GeoJSON demo:
https://opengeo.tech/maps/leaflet-search/examples/geojson-layer.html
Recently, I was looking for an answer, and here is my solution for it
searchControl.on("search:locationfound", function (e) {
if (e.layer._popup) e.layer.openPopup();
});
I have exported the KML file(ICBC.kml)of the 3D model from google earth, and I want to load the 3D model to the google earth plugin, but I can't get the result, many thanks for your suggestion.
javascript code for loading the kml
// Create the placemark.
var placemark = ge.createPlacemark('');
// Get the current view`enter code here`
var myCamera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
// Set new latitude and longitude values
myCamera.setLatitude(30.55552076525944);
myCamera.setLongitude(114.3344795151639);
myCamera.setAltitude(500);
// Placemark/Model/Location
var loc = ge.createLocation('');
loc.setLatitude(myCamera.getLatitude());
loc.setLongitude(myCamera.getLongitude());
// Update the view in Google Earth
ge.getView().setAbstractView(myCamera);
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.OpenTextFile("http://localhost/ICBC.kml",1,true);
var kmlobject = ge.parseKml(f.ReadAll());
ge.getFeatures().appendChild(kmlobject);
var la = ge.createLookAt('');
la.set(30.55552076525944, 114.3344795151639, 500, ge.ALTITUDE_RELATIVE_TO_GROUND, 0, 45, 900);
ge.getView().setAbstractView(la);
If you have the KML file, you shouldn't use parseKml, it's a better practice to use fetchKml, that doesn't need the string of the Kml to be passed, just the URL of the KML.
In your case you should use this line:
var href = UrlOfKML;
google.earth.fetchKml(googleEarthInstance, href, function(kmlObject) {
if (kmlObject)
ge.getFeatures().appendChild(kmlObject);
});
If you have more doubts about the differences of fetchKml and parseKml check this link: Importing KML - GE docs
My client has a very large KML file, it contains around 6000+ placemarks and these placemarks have to appear as 3D models on the map. What's even worse is that the KML file does not contain that <link> tag for the COLLADA file, which means I have to traverse the KML file and attach a COLLADA file before it can be displayed on google earth. Now I can already traverse and add a 3D model for each placemark. I tested it with a very small KML file(which contains like less than 100 placemarks) and it worked great as expected...but when I used the very large KML file which had like 6000+ placemarks on it, the plugin just crashes and I am advised to refresh the browser, only to find it crashing again... :(
Any advice on this?
Is there a limit to the number of placemarks I can put on google earth web plugin?
How do I make the loading faster?
function render3DPoles(polesKmlLink){
google.earth.fetchKml(ge,polesKmlLink, function(object){
if(object){
var item = object.getFeatures().getChildNodes().item(0);
var folder = item.getFeatures().getChildNodes();
var latitude;
var longitude;
for(var i = 0; i<folder.getLength(); i++){
var placemark = folder.item(i);
latitude = placemark.getGeometry().getLatitude();
longitude = placemark.getGeometry().getLongitude();
var model = ge.createModel('');
var location = ge.createLocation('');
model.setLocation(location);
var link = ge.createLink('');
link.setHref('insert URL of collada file here');
model.setLink(link);
location.setLatitude(latitude);
location.setLongitude(longitude);
model.setLocation(location);
placemark.setGeometry(model);
ge.getFeatures().appendChild(placemark);
}
var la = ge.createLookAt('');
la.set(latitude,longitude, 25, ge.ALTITUDE_RELATIVE_TO_GROUND,180, 60, 100);
ge.getView().setAbstractView(la);
} else {
setTimeout(function() {
alert('Bad or null KML.');
},0);
}
});
}
I have dealt with dealing 10,000s of placemarks and other kml objects in the earth plugin and the best way I find is manage the data in a javascript object. dealing with them in standard kml would often crash things.
parse the kml before hand into something that you can handle as an object
start with:
var myModels = {};
for adding the first item if the id is 'foo' or a numeric do something like:
myModels['foo'] = {
description: 'some description for foo',
longitude: 100.12345,
latitude: 45.4567
linkUrl: 'http://mydomain.com/mymodels/foo.dae',
kmlObject: null};
now looking at the code from:
http://code.google.com/apis/ajax/playground/?exp=earth#creating_3d_models
you will have something similar to:
var placemark = ge.createPlacemark('');
placemark.setName('model');
var model = ge.createModel('');
.......
placemark.setGeometry(model);
now go:
myModals['foo'].kmlObject = placemark;
this will give you a quick reference to the model if you need to change it or remove it with just
myModels['foo'].kmlObject
no need to traverse the tree again.
one thing I found to be faster was to define kml client side and use parseKml to load it rather then create individual objects and add them.
also you can build in logic to only add the dae model that are within the area the user is looking at
to loop through all the items
var i, iModel;
for (i in myModels){
iModel = myModels[i];
if(myModels[m].kmlObject == null){
'add if statement to check if the models long/lats are in current view with
' iModel.longitude, iModel.latitude
}
}
also rather than add everything in one operation, add 10-20 model in a single batch and use setTimeout to start another batch operation a second later and leverage .executeBatch
https://developers.google.com/earth/documentation/reference/google_earth_namespace#ab26414915202d39cad12bcd5bd99e739
While there's no technical limit, the more you add the more resources get used. Depending on the complexity of your models and other data, you will be able to add more or less, but 6000 is quite a lot of to display at once even for simple markers.
One solution for a large/complex KML is to create regionated KMLs instead, such that you are loading just the data you need at any given time, based on visible regions (see http://code.google.com/apis/kml/documentation/regions.html )