Google Maps API V3 slow adding Markers using data.addGeoJson - google-maps-api-3

I am adding 325 features to 4 different maps (at different zoom levels) using map.data.addGeoJson(). Roughly half the features are markers and half are polygons. The Polygons render nearly instantaneously. But it takes another 6 full seconds for the markers to show up on the map.
If I only build one map, it still takes 0.5-2 seconds for the markers to show.
Is there anything I can do to speed things up?
Here is my code:
function addSites(map, geoJSON) {
map.data.setStyle(setSitesStyle);
map.data.addGeoJson(geoJSON)
}
function setSitesStyle(feature) {
var searchDist = getSearchDistFromListTypes(feature.getProperty('ListTypes').split('~'));
return ({
fillColor: searchDist.FontColor,
strokeColor: searchDist.FontColor,
strokeWeight: 1,
fillOpacity: .5,
clickable: false,
icon: {
url: 'images/' + searchDist.Marker + 's.png',
size: new google.maps.Size(26 , 38),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(13, 34),
label: feature.getProperty('MarkerNo')
}
});
}
Update: I tried using a simple SVG icon and the performance was no different.

The problem was the DOM was pretty darn big on this page and it took a while for Google Maps to add all of the elements to the DOM.
In my case the page was 95% Handlebars.js so what I did was compile all of the handlebars templates and remember the resulting HTML in an array. Then pushed just the map pages' HTML into the DOM and processed the map data (which was darn fast now.) And then finally loaded the rest of the HTML into the DOM which also was pretty quick.
Since multiple maps can be interspersed throughout the page it was a small challenge to figure out a simple and robust way to get it all woven back together correctly, but I am happy in the end.

Related

Road Label Layer in HERE Maps API for JavaScript

I'm attempting to add a vector map to a webpage using HERE Maps API for JavaScript. I've been using the style code below to render a super minimal style akin to the 4th picture from the top at this link (the one with only road and water area layers).
sources:
omv:
type: OMV
max_zoom: 17
min_display_zoom: 1
# global description of the map, in this example
# the map background color is white
scene:
background:
color: [1.000, 1.000, 1.000, 1.00]
# section contains the style information for the layers
# that are present on the map
layers:
# user defined name of the rendering layer
water_areas:
# the section defines where the rendering layer takes
# its data from source: omv is mandatory for the Vector Tile API
# layer: water specifies what vector layer is taken
# for the rendering see REST API documentation for the
# list of available layers.
data: {source: omv, layer: water}
# section defines how to render the layer
draw:
polygons:
order: 1 # z-order of the layer
color: [0.055, 0.604, 0.914, 1.00]
road:
data: {source: omv, layer: roads}
draw:
lines:
order: 2
color: [0.561, 0.561, 0.561, 1.00]
width: 15
It wasn't difficult to figure out how to add things like geoshape overlays and UI controls and panning, but the one thing I haven't been able to add successfully is road labels. (Which seems like it'd be quite easy.)
I've attempted to grab code for road label layers from other documentation examples, but it always breaks the map (leaving only my geoshapes on a white background). This may be because there's always global variable attached to the label's language or fill color, but when I attempt to bring in all the global variable settings and references, the map is still broken.
So my question is, does anyone know of a simple/foolproof way to add road labels to a HERE map with such a minimal style? I suppose I'm looking for the minimum attributes necessary to make that layer visible. Thanks!
To better way to rework (delete section/add yours) vector styles to utilize the online editor Map Style editor (it allows you see changes immediately) and after that load reworked style yaml file in your web app like:
function setStyle(map) {
// get the vector provider from the base layer
var provider = map.getBaseLayer().getProvider();
// Create the style object from the YAML configuration.
// First argument is the style path and the second is the base URL to use for
// resolving relative URLs in the style like textures, fonts.
// all referenced resources relative to the base path https://js.api.here.com/v3/3.1/styles/omv.
var style = new H.map.Style('URL/to/your.yaml',
'https://js.api.here.com/v3/3.1/styles/omv/');
// set the style on the existing layer
provider.setStyle(style);
}
See please the example on https://jsfiddle.net/qw64zL85/
There is using this yaml example file with road_labels: there only yaml text

Leaflet js: How to count the layers in Layer Group?

I would like to make such a map that only allows checking/showing 2 layers at a time and it should show some warning if chosen more.
After searching the internet, and taking a look at these possible solutions and references: first, second, third etc.
...I still can't get my code to do this simple thing: to count the layers in a layer group and according to that, to show a message.
Here my code:
var NumbActive = new L.layerGroup();
NumbActive.addTo(map);
map.on('overlayadd',function(active){
if (active.layer===LAY1){
NumbActive.addLayer(LAY1);
}});
map.on('overlayadd',function(active){
if (active.layer===LAY2){
NumbActive.addLayer(LAY2);
}});
map.on('overlayadd',function(active){
if (active.layer===LAY3){
NumbActive.addLayer(LAY3);
}});
size = NumbActive.getLayers().length;
var options = { timeout: 5000 };
var box = L.control.messagebox(options).addTo(map);
if (size >2){
box.show( 'Please choose only 2 layers at the same time!' );
};
I am also using this plugin for showing messages, which normally works fine, but in this case not at all.
I thought that layerGroup.getLayers().length should give a number as a result (length of an array)? It should work but somehow it doesn't.
Please tell me your suggestions. It can't be that complicated. I would just like to know if I'm making some minor mistake that's possible to be corrected or should I write some new function/search for a plugin.
Thanks in advance! :)

Google Maps v3 Fit the Contents of Multiple Info Windows

I would like to make the contents of this infowindow to fit. I just fork this code from this post.
So far, I've manage to try the following links as the result of my research
The first answer on this link seems to work in the year 2010, but no longer
works in 2014, or maybe I'm just missing something.
It states that
set the maxWidth options property in the constructor. Yes, even if setting the maximum width was not what you wanted to do.
then one of the comment says that maybe this is working in year 2010 but not anymore in 2014
This may have worked in 2010, but does not help as of 2014. – Simon Aug 15 at 1:25
This link replaces the "standard" google maps infowindow with our own style, but this doesn't work also to me.
What you want to do is replace the "standard" Googlemaps infoWindow with your own, and put your content into it. Once you replace the standard GM infoWindow, you have a lot of latitude to work with.
I've also tried this, but the code doesn't fit my codes.
Below is the code that I've tried
content: $(this.infocontent)[0]
Lastly is this, which aims on resizing the infowindow but it doesn't work still.
var infowindow = new google.maps.InfoWindow({
content: ...,
maxWidth: 300
})
Something like this is the result that I want to get, when we click the marker, an infowindow that can autofit will show.
This is not the fix, but just a work around. Didn't permanently fixed the problem.
It seems that by changing the code of this
var sites = [
['American Range', 34.2737729, -118.4284391, 1, "<a href=\"http://americanrange.com/\" target='_blank'>American Range</a>"],
['Gorenje', 46.3446568, 15.0064148, 1, "<a href=\"http://www.gorenje.com/\" target='_blank'>Gorenje</a>"]
];
To this
var sites = [
['American Range', 34.2777032, -118.4238387, 1, '<p><b>American Range</b></p></br>'],
['Gorenje', 46.4906673, 15.3754774, 1, '<p><b>Gorenje</b></p></br>']
];
Specifically this
"<a href=\"http://americanrange.com/\" target='_blank'>American Range</a>"
To this
'<p><b>American Range</b></p></br>'
Fixes the problem for certain marker, but not all.

JSNewtworkX stop layout

i'm using JSNetworkX for graph exploration and rendering.
JSNetworkX is using D3.js for graph render. However, as I work with large graph (json file about 5Mb), I would like to render this graph directly without any animations (so, in placing each node directly without force attraction).
I try to use D3.layout.force().stop() after rendering, but it's without effects.
Because of that, I'm thinking that it has to be done in jsnx.draw, see my code below.
jsnx.draw(G, {
element: 'body',
d3: d3,
layout_attr: {
charge: -1500,
linkDistance: 1,
gravity: 1,
friction: 0.4,
alpha: -100
},
});
force = d3.layout.force();
Unfortunately, you can't do that with the current version. Do you need a force layout at all or do you already have positions for each node? FWIW, if you really have a large graph, even a static layout would be slow, because you'd still have too many SVG elements. The next version will include a WebGL rendered for large graphs.
So, we can't for the moment.
As of v0.3.4, jsnx.draw returns the force layout object so you can do var force = jsnx.draw{/*...*/} then force.stop().

Multiple script/paperscripts in the same paperscope

I'm starting with paper.js. I like the fact that it introduces the possibility to have a script with a text/paperscript mime type, which runs in its on scope. However, scripts can become large pretty soon, so I want to be able to divide it in multiple scripts for readability. I thought I could just add more than one script tag and have them all run in the same scope, but apparently this isn't the case.
Both scripts are loaded and do run, but the second script doesn't seem to be in the paper scope.
I've set up an example here: http://barbata.nl/SO/Maps/ This example has some code, but I'll point out the important bits.
It contains two paperscripts:
Maps.js is the main script, which rasterizes the image and allows moving it around. You can ignore the code in this script, for it works fine so far.
Zoom.js is the script in which I wanted to isolate zooming functionality. It uses jq.mobi to capture the scroll wheel of the mouse, since Paper.js doesn't seem to have that event. It then translates that to a call to onMouseScroll, in a similar way Paper does it.
So far so good. The actual problem arises with the zoomIn and zoomOut functions in zoom.js.
It works if I explicity use the paper object to reference the view I want to zoom:
function zoomIn()
{
if (paper.view.zoom < 2)
{
paper.view.zoom = paper.view.zoom * 2;
}
}
But it fails when I remove paper and just reference the view:
function zoomIn()
{
if (view.zoom < 2)
{
view.zoom = view.zoom * 2;
}
}
This surprises me, as I expected the script to be a Paperscript, running in the Paperscope. It works fine if I put this code in Maps.js, so it seems that although zoom.js is loaded by Paper.js (the developer tools in the browser confirm this), it isn't run in the Paperscope.
My question is: are my findings correct? Am I doing something wrong? What is the right way to divide a Paper.js application into multiple units for readability?
Of course I can get it running, but I want to make sure I do it right.
This is indeed how it works. I've opened an issue on GitHub
I found that the "cleanest" way is to do it with this.install(window). It also makes error finding with Chrome developer tools easier since it is more adapted to reporting on the line errors in java-script than "paperscript".
in index.html (for example):
<script type="text/javascript" src='js/other_lib.js'></script>
<script type="text/paperscript" canvas="canvas">
this.install(window);
/*no code 'required' here */
</script>
<body>
<canvas id="canvas" width="1500" height="500"></canvas>
</body>
Then in the js/other_lib.js i just add code as normal:
var r = new Path.Rectangle([100,100],[200,200]);
r.fillColor = 'black';
/*more code here*/
This should generate a rectangle.
What DOES'T NOT WORK for me (as of Paper.js v0.10.2 Release Date: 9. July 2016) is the object operators. Such as adding vecrots pointc = pointa + pointb; for me this is giving a lot of NaN values.
I have had to edit a few libs to get this working, but the change is simple:
var pointc = new Point(pointa.x+pointb.x,pointa.y + pointb.y);

Resources