Well I'm trying to combine 2 examples to search from my geojson file, and when selected it will zoom that property.
Search (search in GeoJSON one) http://labs.easyblog.it/maps/leaflet-search/examples/
Zoom part from here (without the dropdown) http://projects.bryanmcbride.com/leaflet/select_zoom.html
Basically the first one just with zoom from second. I have been able to get them working, but separately.
Codes (1.)
var featuresLayer = new L.GeoJSON(piirid, {
style: function(f) {
return {color: f.properties.color };
}
});
map.addLayer(featuresLayer);
var searchControl = new L.Control.Search({layer: featuresLayer, propertyName: 'L_AADRESS', circleLocation:false});
searchControl.on('search_locationfound', function(e) {
e.layer.setStyle({fillColor: '#3f0', color: '#0f0'});
}).on('search_collapsed', function(e) {
featuresLayer.eachLayer(function(layer) { //restore feature color
featuresLayer.resetStyle(layer);
});
});
map.addControl( searchControl ); //inizialize search control
Code 2.
// Loop through the geojson features and extract bbox and name, then add the options to the "zoom" select (no jQuery)
/*var select = document.getElementById("zoom");
select.options[select.options.length] = new Option('Select a State', 'Select a State');
for (each in geojson._layers) {
var bbox = geojson._layers[each].getBounds()._southWest.lat + "," + geojson._layers[each].getBounds()._southWest.lng + "," + geojson._layers[each].getBounds()._northEast.lat + "," + geojson._layers[each].getBounds()._northEast.lng;
select.options[select.options.length] = new Option(geojson._layers[each].feature.properties.name, bbox);
}*/
// Loop through the geojson features and extract bbox and name, then add the options to the "zoom" select and build autocomplete(using jquery)
var options = '<option value="Select a State">Select a State</option>';
var states = [];
for (each in geojson._layers) {
var L_AADRESS = geojson._layers[each].feature.properties.L_AADRESS;
var swLat = geojson._layers[each].getBounds()._southWest.lat;
var swLng = geojson._layers[each].getBounds()._southWest.lng;
var neLat = geojson._layers[each].getBounds()._northEast.lat;
var neLng = geojson._layers[each].getBounds()._northEast.lng;
var bbox = swLat + "," + swLng + "," + neLat + "," + neLng;
// Populate states array and build autocomplete
states.push({label: L_AADRESS, value: L_AADRESS, swlat: swLat, swlng: swLng, nelat: neLat, nelng: neLng});
$( "#search" ).autocomplete({
source: states,
minLength: 3,
select: function( event, ui ) {
map.fitBounds([[ui.item.swlat, ui.item.swlng],[ui.item.nelat, ui.item.nelng]]);
}
});
// Add states & bbox values to zoom select options
options += '<option value="' + bbox + '">' + geojson._layers[each].feature.properties.L_AADRESS + '</option>';
}
If I understand your question correctly you just have to add:
map.fitBounds(e.layer.getBounds());
to the search_locationfound event function.
This will set the maximum zoom level that you can still see the whole layer.
So the search_locationfound event function from your first example would be:
searchControl.on('search_locationfound', function(e) {
map.fitBounds(e.layer.getBounds());
e.layer.setStyle({fillColor: '#3f0', color: '#0f0'});
});
jsfiddle
Related
Imagine that we have a pie chart like the code bellow:
am4core.ready(function() {
// Create chart instance
chartReg[id] = am4core.create(id, am4charts.PieChart);
// Add data
chartReg[id].data = data;
chartReg[id].innerRadius = 60;
// Add and configure Series
var pieSeries = chartReg[id].series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = "value";
pieSeries.dataFields.category = "key";
pieSeries.ticks.template.disabled = true;
pieSeries.alignLabels = false;
// Create custom legend
chartReg[id].events.on("ready", function(event) {
// populate our custom legend when chart renders
chartReg[id].customLegend = $('#legend');
pieSeries.dataItems.each(function(row, i) {
var color = pieSeries.colors.getIndex(i);
var percent = Math.round(row.values.value.percent * 100) / 100;
var value = row.value;
var title = row.category
legend.innerHTML += '<div class="legend-item" id="legend-item-' + i + '" onclick="toggleSlice(' + i + ');" onmouseover="hoverSlice(' + i + ');" onmouseout="blurSlice(' + i + ');"><div class="legend-marker" style="background: ' + color + '"></div><div class="legend-title">' + title + '</div><div class="legend-value">' + value + ' | ' + percent + '%</div></div>';
});
});
});
The custom legends work fine like bellow:
But if we have multiple pie charts that get rendered in the DOM at the same time, the legends don't show up!
❤❤ Thank you for reading my question. ❤❤
I found the answer. Insted of:
legend.innerHTML += '<div>...</div>';
We should use:
$('#legend_'+id).append('<div>...</div>');
that dynamically adds the legends to the related div ;)
I am referring to another question display select options based on previous selections
I have while loop to fill the var data and inside a foreach loop to give the sub-menu and all work fine, var data = {'B|1':['B5|1','B4|2']
now after displaying menu1 How do I display second one, am just stopped there.
my code is:
for (var i in data) {
var ii = i.split('|');
$('#menu1').append('<option value=' + ii[1] + '>' + ii[0] + '</option>');
}
$('#menu1').change(function () {
var key = $(this).val();
$('#menu2').empty();
for (var i in data[key]) {
var ii = data[key][i].split('|');
$('#menu2').append('<option value=' + ii[1] + '>' + ii[0] + '</option>');
}
}).trigger('change');
menu1 is ok, now I need to show #menu2 with the value and text ??
This may help you
$('#menu1').change(function() {
var key = $(this).val();
var keyText = $('#menu1 :selected').text();
$('#menu2').empty();
for (var i in data[keyText +"|" + key]) {
var ii=data[keyText +"|" + key][i].split('|');
$('#menu2').append('<option value='+ii[1]+'>' + ii[0] + '</option>');
}
}).trigger('change');
I am new to JS and need help in understanding it's scope in my use case.
The following function displays information on mouseover on the chart tool tip.
function renderTooltip(data, item) {
//this.setTitle(item.yField + ' : ' + item.value[1]);
var Data = item.value[1];
var TestData = item.storeItem;
this.update(''
+ '<table>'
+ '<tr><td><b>Name:</b> </td><td>' + TestData.get('Name') + '</td></tr>'
+ '<tr><td><b>Value:</b> </td><td>' + Data + '</td></tr>'
);
var e = window.event;
var t = e.target || e.srcElement;
t.onclick=function(event){
window.location = "{!$Page.ABCDPage}?id="+TestData.get('Name')+'/'+Data ;
};
}
In addition to this , I want the tooltip symbol to change and the colour to be different , based on a ceratin value of a field in the record.
e.g if field 1== value 1 , symbol should be cross and colour blue , else box and colour green
Is that possible?
I develop a website with Openlayers 3 and need to yours helps.
My web page is shared in two parts: the listing display and map display.
I have create the markers that is animated by the cluster.
var features = [];
$.ajax({
url: urlUpdate,
dataType: 'json',
async: false,
success: function(json1){
$.each(json1, function (key, data) {
if (key === 'features') {
$.each(data, function (k, v) {
if (v.type === 'Feature') {
if (v.geometry.coordinates.length > 1){
features[k] = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(v.geometry.coordinates, 'EPSG:4326', 'EPSG:3857')),
id: v.properties.id,
name: v.properties.name,
lieu: v.properties.lieu,
});
}
}
});
}
});
}
});
var source = new ol.source.Vector({
features: features
});
var clusterSource = new ol.source.Cluster({
distance: 40,
source: source
});
var clusters = new ol.layer.Vector({
source: clusterSource,
style: ajouterStyle
});
var oldMarkers = map.getLayers().a[2];
map.removeLayer(oldMarkers);
map.addLayer( clusters );
The listing display need to update the map displaying and vice versa.
map.getView().on('change:resolution', function(evt){
var myLayer = map.getLayers().getArray()[2];
myLayer.getSource().forEachFeature(function(feature){
var geom = feature.getGeometry();
var coord = geom.getCoordinates(); //this is valid for a ol.geom.Point
var nb = feature.get('features').length;
var content = '';
if( nb === 1 ){
var name = feature.get('features')[0].get("name");
var date = feature.get('features')[0].get("date");
var id = feature.get('features')[0].get("id");
var content = '<li class="events">\n\
<div class="content_events">\n\
'<a href="?event=' + id +'" >' + name + "</a>\n\
<p>" + date + "</p>\n\
</div>\n\
</li>";
} else{
for( i=0; i< nb; i++){
var name = feature.get('features')[i].get("name");
var date = feature.get('features')[i].get("date");
var id = feature.get('features')[i].get("id");
content += '<li class="events">' +
'<div class="content_events">\n\
'<a href="?event=' + id + '" >' + name + "</a>"+
"<p>" + date + "</p>\n\
</div>\n\
</li>";
}
$("#listing_events").html('<ul class="list-event">' + content + '</ul>')
});
With this method I get the information of all markers, I need to get the marker displayed on the screen.
Thanks for your helps.
I have resolve my problem by :
var source = new ol.source.Vector({ features: features }); var bb = source.getExtent(); map.getView().fitExtent( bb, map.getSize() );
Thanks
I've gone through the forums trying to search for solutions, and I've adapted my code for several problems I've come across, but this one eludes me. I'm trying to plot multiple points on a map (which works) and then draw lines between the points. Each marker contains information, such as latitude and longitude, as well as it's neighbor (the point that I want to draw the line to). I also give it the color I want the line, as different 'routes' can be in different colors. The only I can see being a problem is that I draw a line, set it on the map, and run the loop again for the next marker.
My code places the markers, places the information window for each marker, but doesn't draw the lines between the markers. Can anyone see where I've screwed up, or even if this is possible to do it in the way I'm doing it?
The reason I'm keeping the drawMap function separate is in the event users want to filter out visible data, I need to re-draw the map dynamically. So, I'm keeping the marker list globally so I can reference it even after the function has finished.
My code:
http://www.nku.edu/~sweikatam1/nkuPhysicalMapTest.html
The spot in particular with the issue is the function drawMap, which gets passed an array of objects, markerList, containing the latitude, longitude, color (for the polyline), and other bits of data.
The line placement:
for(var j = 0; j < markerList.length; j++){
if(markerList[j].name == markerList[i].neighbor){
var targetDestination = new google.maps.LatLng(markerList[j].latitude,markerList[j].longitude);
//alert(markerList[i].latitude + " " + markerList[i].longitude + " \r" + markerList[j].latitude + " " + markerList[j].longitude);
}
}
//set the pathway for the two points
var flightPlanCoordinates = [
new google.maps.LatLng(markerList[i].latitude, markerList[i].longitude),
new google.maps.LatLng(targetDestination)
];
//alert("Color: " + markerList[i].routeColor);
//set the line and color
var flightPath = new google.maps.Polyline({
path:flightPlanCoordinates,
strokeColor:markerList[i].routeColor,
strokeOpacity:2,
strokeWeight:5
});
//apply lines
flightPath.setMap(map);
The function as a whole:
function drawMap(markerList){
//alert("Starting drawMap");
//create the map
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
center: new google.maps.LatLng(39.032253, -84.465015),
mapTypeId: google.maps.MapTypeId.HYBRID
});
var marker;
for (var i = 0; i <markerList.length; i++){
/*alert("markerList # i: " + markerList[i].name);
alert("Marker Data: " + "Name: " + markerList[i].name + "\r "
+ "Latitude: " + markerList[i].latitude + "\r "
+ "Longitude: " + markerList[i].longitude + "\r "
+ "Content Type: " + markerList[i].contentType + "\r "
+ "Image: " + markerList[i].image
+ "Color: " + markerList[i].routeColor);*/
var contentData = '<b>'+markerList[i].name +'</b>: '
+ markerList[i].latitude + ' x '
+ markerList[i].longitude + '<br/><p>'
+ markerList[i].contentType
+'</p><img src="' + markerList[i].image + " height=150 width=100>";
//create the marker
marker = new google.maps.Marker({
position: new google.maps.LatLng(markerList[i].latitude,markerList[i].longitude),
draggable: false,
icon: markerList[i].icon,
map:map,
content: contentData,
title:markerList[i].name
});
//find the neighbor for the current marker and set the destination coordinates
for(var j = 0; j < markerList.length; j++){
if(markerList[j].name == markerList[i].neighbor){
var targetDestination = new google.maps.LatLng(markerList[j].latitude,markerList[j].longitude);
//alert(markerList[i].latitude + " " + markerList[i].longitude + " \r" + markerList[j].latitude + " " + markerList[j].longitude);
}
}
//set the pathway for the two points
var flightPlanCoordinates = [
new google.maps.LatLng(markerList[i].latitude, markerList[i].longitude),
new google.maps.LatLng(targetDestination)
];
//alert("Color: " + markerList[i].routeColor);
//set the line and color
var flightPath = new google.maps.Polyline({
path:flightPlanCoordinates,
strokeColor:markerList[i].routeColor,
strokeOpacity:2,
strokeWeight:5
});
//apply lines
flightPath.setMap(map);
//handle open information windows
google.maps.event.addListener(marker,'click', function(){
closeInfos();
var info = new google.maps.InfoWindow({content: this.content});
info.open(map,this);
infos[0]=info;
});
//alert("Marker " + markerList[i].name + " placed.");
}
//alert("drawMap complete. Drawing lines");
<!-- DRAWING LINES COMPLETE -->
}
If anything here seems odd, confusing, or needs clarification, please let me know. Criticisms and ways of doing things better are always welcome. Thanks guys!
In defining, flightPlanCoordinates, the second LatLng was being created out of another LatLng (targetDestination). So just remove the new google.maps.LatLng portion and use the targetDestination directly. With this change, I saw a blue zigzag and a red one being drawn on the map.
var flightPlanCoordinates = [
new google.maps.LatLng(markerList[i].latitude, markerList[i].longitude),
targetDestination
];