I have function to show map on my website. It works well for desktop version, but does not on mobile. It does not affect nor bounds nor zoom level. Map is centered somewhere...
services_vars.search_lat = ''
services_vars.search_lng = ''
parseInt(services_vars.zoom) = 14
if($('#mapView').length > 0) {
var propsAjaxURL = services_vars.admin_url + 'admin-ajax.php';
var propsSecurity = $('#securityAppMap').val();
$.ajax({
type: 'POST',
dataType: 'json',
url: propsAjaxURL,
data: {
'action': 'reales_get_searched_properties',
'country': services_vars.search_country,
'state': services_vars.search_state,
'city': services_vars.search_city,
'category': services_vars.search_category,
'type': services_vars.search_type,
'min_price': services_vars.search_min_price,
'max_price': services_vars.search_max_price,
'bedrooms' : services_vars.search_bedrooms,
'bathrooms' : services_vars.search_bathrooms,
'neighborhood' : services_vars.search_neighborhood,
'min_area' : services_vars.search_min_area,
'max_area' : services_vars.search_max_area,
'amenities': services_vars.search_amenities,
'page': services_vars.page,
'sort': services_vars.sort,
'security': propsSecurity
},
success: function(data) {
appMap = new google.maps.Map(document.getElementById('mapView'), options);
var styledMapType = new google.maps.StyledMapType(styles, {
name : 'Styled'
});
appMap.mapTypes.set('Styled', styledMapType);
appMap.getStreetView().setOptions(panoramaOptions);
var searchedPosition = new google.maps.LatLng(services_vars.search_lat, services_vars.search_lng);
appMap.setCenter(searchedPosition);
appMap.setZoom(parseInt(services_vars.zoom));
if(data.getprops === true) {
addMarkers(data.props, appMap);
appMap.fitBounds(markers.reduce(function(bounds, marker) {
return bounds.extend(marker.getPosition());
}, new google.maps.LatLngBounds()));
google.maps.event.trigger(appMap, 'resize');
}
},
error: function(errorThrown) {
}
});
}
Related
I have to put markes on google maps, but the array with lat, long is made by an Ajax request.
Map is loaded before the initialization of the array and I don't see the markers.
I think that this is the problem but I'm not so sure. hope you can help me
<script>
$(document).ready(function() {
setVariable('<?php echo $_SESSION["token"]?>');
});
</script>
<script defer
src="https://maps.googleapis.com/maps/api/js?key=XXXXXXXXXXXXXXX&callback=initMap">
</script>
coord = new Array();
function setVariable(token) {
format="text/plain";
$.ajax({
url: BASE_URL + "reports",
type: "GET",
contentType: "application/json; charset=utf-8",
headers: {'x-access-token': token},
cache: false,
success: function(data){
if (data.success){
$.each(data.data.reports, function (i, item) {
coord[i] = [ data.data.reports[i].lat , data.data.reports[i].lng ] ;
});
console.log(coord)
}else{
alert(data.error.message);
}
},
error: function(data){
console.log(data);
}
});
}
function initMap() {
var myLatLng = {lat: 43.1107168, lng: 12.3908279};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: myLatLng
});
var marker, i;
for (i = 0; i < coord.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(coord[i][0], coord[i][1]),
map: map,
title: 'Hello World!'
});
}
}
How can i resolve this?
thank you very much.
You will need to restructure the code in order to make this work. We need to add markers on the map only after we have fetched the lat/long data successfully by making an AJAX request. We could do this in the following manner.
<script defer
src="https://maps.googleapis.com/maps/api/js?key=XXXXXXXXXXXXXXX&callback=initMap">
/*
We will keep a global variable that would contain a reference to the google map object.
It would be initialized as soon as the script for google maps is loaded and initMap function is called subsequently.
*/
var GoogleMap;
coord = new Array();
function setVariable(token) {
format="text/plain";
$.ajax({
url: BASE_URL + "reports",
type: "GET",
contentType: "application/json; charset=utf-8",
headers: {'x-access-token': token},
cache: false,
success: function(data){
if (data.success){
$.each(data.data.reports, function (i, item) {
coord[i] = [ data.data.reports[i].lat , data.data.reports[i].lng ] ;
});
console.log(coord)
var marker, i;
for (i = 0; i < coord.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(coord[i][0], coord[i][1]),
map: GoogleMap,
title: 'Hello World!'
});
}
}else{
alert(data.error.message);
}
},
error: function(data){
console.log(data);
}
});
}
function initMap() {
var myLatLng = {lat: 43.1107168, lng: 12.3908279};
GoogleMap = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: myLatLng
});
}
Hopefully, this should work!
Here I want to do which are the variable not empty, I want to pass that variable one in data,in this case area is empty so I want pass the parameter for city and listing type, but I don't know how to do?
var city = "Karnadaka";
var area = "";
var listing type = "RENT";
$.ajax({
type: 'GET',
url: "http://www.domain.com/api/get/searchProperties",
data: {
area: area,
city: city,
listingType: listing_type
},
success: function(data) {
console.log(data);
}
});
you can use delete to remove the propery pair(s) in an Object
var city = "Karnadaka";
var area = "";
var listing_type = "RENT";
var data={
area: area,
city: city,
listingType: listing_type
}
for (k in data){
if(data[k]=="") delete data[k];
}
$.ajax({
type: 'GET',
url: "http://www.domain.com/api/get/searchProperties",
data: data,
success: function(data) {
console.log(data);
}
});
Try this:
var city = "Karnadaka";
var area = "";
var listing_type = "RENT";
var data = {};
if(city != '')
data['city'] = city;
if(area != '')
data['area'] = area;
if(listing_type != '')
data['listing_type'] = listing_type;
$.ajax({
type: 'GET',
url: "http://www.domain.com/api/get/searchProperties",
data: data,
success: function(response) {
console.log(response);
}
});
I have a code which I request data from a geoserver and display geoJSON on a map. To this request I'm using three AJAX calls like the following:
$(document).ready(function(){
//BASEMAP
var center = new L.LatLng(-0.8936,119.8638);
var map = new L.Map('map', { center: center, zoom: 14, attributionControl:true, zoomControl:false});
osmTile = "http://tile.openstreetmap.org/{z}/{x}/{y}.png";
osmCopyright = "Map data © 2016 OpenStreetMap contributors";
osmLayer = new L.TileLayer(osmTile, { maxZoom: 18, attribution: osmCopyright } );
map.addLayer(osmLayer);
//URL SERVICE
var owsrootUrl = 'http://sample.com/geoserver/ows';
//different color in layers
function getColor(d) {
return d > 10000 ? '#FF0000' :
d > 5000 ? '#FF9900' :
d > 2000 ? '#E31A1C' :
d > 1000 ? '#00FF00' :
d > 500 ? '#FD8D3C' :
d > 200 ? '#0000CC' :
d > 100 ? '#FED976' :
'#FFEDA0';
}
function style(feature) {
return {
weight: 1,
opacity: 3,
color: 'white',
dashArray: '3',
fillOpacity: 3,
fillColor: getColor(feature.properties.luas_tanah)
};
}
var lyr_1 = new L.LayerGroup();
var lyr_2 = new L.LayerGroup();
var lyr_3 = new L.LayerGroup();
var lyr_4 = new L.LayerGroup();
var defaultParameters = {
service : 'WFS',
version : '1.0.0',
request : 'GetFeature',
typeName : 'pbb:view_map',
maxFeatures: 1000,
outputFormat : 'text/javascript',
format_options : 'callback:getJson',
SrsName : 'EPSG:4326'
};
var parameters = L.Util.extend(defaultParameters);
var URL = owsrootUrl + L.Util.getParamString(parameters);
var lyr_1 = new L.LayerGroup();
var ajax1 = $.ajax({
type: 'GET',
url : URL,
dataType : 'jsonp',
async: false,
jsonpCallback : 'getJson',
success : function (response) {
console.log("Layer 1");
L.geoJson(response, {
style: function (feature) {
return {
stroke: true,
color: getColor(feature.properties.luas_tanah),
opacity: 1,
weight: 1
};
},
onEachFeature: function (feature, layer) {
popupOptions = {maxWidth: 200};
layer.bindPopup("<b>D NOP : </b> " + feature.properties.d_nop
,popupOptions);
}
}).addTo(lyr_1);
},
error: function (xhr, status) {
alert("Failed call Layer A");
}
});
var defaultParameters1 = {
service : 'WFS',
version : '1.0.0',
request : 'GetFeature',
typeName : 'pbb:view_map',
maxFeatures: 1000,
outputFormat : 'text/javascript',
format_options : 'callback:getJson',
SrsName : 'EPSG:4326'
};
var parameters1 = L.Util.extend(defaultParameters1);
var URL1 = owsrootUrl + L.Util.getParamString(parameters1);
var lyr_2 = new L.LayerGroup();
var ajax2 = $.ajax({
type: 'GET',
url : URL1,
dataType : 'jsonp',
async: false,
jsonpCallback : 'getJson',
success : function (response) {
console.log("Layer 2");
L.geoJson(response, {
style: function (feature) {
return {
stroke: true,
color: getColor(feature.properties.luas_tanah),
opacity: 0.8,
weight: 1
};
},
onEachFeature: function (feature, layer) {
popupOptions = {maxWidth: 200};
layer.bindPopup("<b>D NOP : </b> " + feature.properties.d_nop
,popupOptions);
}
}).addTo(lyr_2);
},
error: function (xhr, status) {
alert("Failed call Layer B");
}
});
var defaultParameters2 = {
service : 'WFS',
version : '1.0.0',
request : 'GetFeature',
typeName : 'pbb:view_map',
maxFeatures: 1000,
outputFormat : 'text/javascript',
format_options : 'callback:getJson',
SrsName : 'EPSG:4326'
};
var parameters2 = L.Util.extend(defaultParameters2);
var URL2 = owsrootUrl + L.Util.getParamString(parameters2);
var lyr_3 = new L.LayerGroup();
var ajax3 = $.ajax({
type: 'GET',
url : URL2,
dataType : 'jsonp',
async: false,
jsonpCallback : 'getJson',
success : function (response) {
console.log("Layer 3");
L.geoJson(response, {
style: function (feature) {
return {
stroke: true,
color: getColor(feature.properties.luas_tanah),
opacity: 0.8,
weight: 1
};
},
onEachFeature: function (feature, layer) {
popupOptions = {maxWidth: 200};
layer.bindPopup("<b>D NOP : </b> " + feature.properties.d_nop
,popupOptions);
}
}).addTo(lyr_3);
},
error: function (xhr, status) {
alert("Failed call Layer C");
}
});
var defaultParameters3 = {
service : 'WFS',
version : '1.0.0',
request : 'GetFeature',
typeName : 'pbb:view_map',
maxFeatures: 1000,
outputFormat : 'text/javascript',
format_options : 'callback:getJson',
SrsName : 'EPSG:4326'
};
var parameters3 = L.Util.extend(defaultParameters3);
var URL3 = owsrootUrl + L.Util.getParamString(parameters3);
var lyr_4 = new L.LayerGroup();
var ajax4 = $.ajax({
url : URL3,
dataType : 'jsonp',
async: false,
jsonpCallback : 'getJson',
success : function (response) {
console.log("Layer 4");
L.geoJson(response, {
style: function (feature) {
return {
stroke: true,
color: getColor(feature.properties.luas_tanah),
opacity: 0.8,
weight: 1
};
},
onEachFeature: function (feature, layer) {
popupOptions = {maxWidth: 200};
layer.bindPopup("<b>D NOP : </b> " + feature.properties.d_nop
,popupOptions);
}
}).addTo(lyr_4);
},
error: function (xhr, status) {
alert("Failed call Layer D");
}
});
var baseMaps = [
{
groupName : "OSM Base Maps",
layers : {
"OpenStreetMaps" : osmLayer
}
}
];
var overlays = [
{
groupName : "Kecamatan",
expanded : true,
layers : {
"Layer A" : lyr_1,
"Layer B" : lyr_2,
"Layer C" : lyr_3,
"Layer D" : lyr_4
}
}
];
var options = {
container_width : "300px",
group_maxHeight : "800px",
exclusive : true
};
var control = L.Control.styledLayerControl(baseMaps, overlays, options);
map.addControl(control);
var legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = [0, 100, 200, 500, 1000, 2000, 5000, 10000],
labels = [],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
labels.push(
'<i style="background:' + getColor(from + 1) + '"></i> ' +
from + (to ? '–' + to : '+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
legend.addTo(map);
});
Now my problem is every time I open the page everything work just fine, but sometimes when I refresh the page everything breaks apart. For example some times "Layer A" data is displayed, some times data ends up on the wrong dataset. When I get this bug I get the following message in the console:
ows?service=WFS&version=1.0.0&request=GetFeature&typeName=pbb%3Aview_map&maxFeatures=1000&outputFor…:1 Uncaught TypeError: getJson is not a function
On my research it seems that this type of error is quite common when running multiple AJAX calls. What I don't understand is why this error does not occur 100% of the time. What type of techniques can be used to fix it? I heard of Deffered Objects but could not apply it on my code, my expertise level on this is far from great. Although this may tend towards a GIS question I believe that this type of issue is more related to ordinary jQuery and Asynchronous calls.
jsonpCallback Type: String or Function() Specify the callback function
name for a JSONP request. This value will be used instead of the
random name automatically generated by jQuery. It is preferable to let
jQuery generate a unique name as it'll make it easier to manage the
requests and provide callbacks and error handling.
Don't use it.
Remove this line:
jsonpCallback : 'getJson',
When you have multiple requests in flight at once, their callback functions (since you are forcing them to use the same name) overwrite each other.
async: false
Making a synchronous request would resolve the problem (since you can't have multiple synchronous requests in flight at once (they queue)) … but they are:
Horrible (they are deprecated in XHR on the main browser thread with good reason)
Completely incompatible with JSONP (so your instruction is ignored).
You should remove the attempt to make the request synchronous too.
I have been using the example shown here (https://astuntechnology.github.io/osgis-ol3-leaflet/ol3/05-WMS-INFO.html) to try and retrieve features at a coordinate from multiple TileWMS layers I have set up in my application.
This example has been tweaked so it now returns data in JSONP using the reqwest library, but now I am trying to figure out the best way to adapt this to include multiple layers and multiple features.
I am thinking of using the map.forEachLayerAtPixel function to retrieve all layers present at the map click location, and then within if statements call the feature and add this to a variable to build a dynamic html table of results.
I don't know if this is the best approach but is the only way I can think of doing it so I am able to retrieve the information in a way I can lay it out specifically.
Below is the javascript for my on map click function but it is not returning the pop up and doesn't display any errors.
I am not sure if I am using the correct approach, and does anything look incorrect with the below?
Thanks
var popup = new ol.Overlay.Popup();
map.addOverlay(popup);
map.on('singleclick', function(evt) {
if($(window).width() <= 767 && document.getElementById('sidebar').style.display == 'block') {
$('#sidebar').toggle();
$(".navbar-collapse.in").collapse("hide");
map.updateSize();
return false;
}
// Hide existing popup and reset it's offset
popup.hide();
popup.setOffset([0, 0]);
var displayedLayers = [];
var content = "";
map.forEachLayerAtPixel(evt.pixel, function(layer) {
displayedLayers.push(layer.get('name'));
});
if ($.inArray('layer62', displayedLayers) > -1) {
var url = layer62
.getSource()
.getGetFeatureInfoUrl(
evt.coordinate,
map.getView().getResolution(),
map.getView().getProjection(),
{
'INFO_FORMAT': 'text/javascript',
'format_options': 'callback:results',
'propertyName': 'definition'
}
);
reqwest({
url: url,
type: 'jsonp',
jsonpCallbackName: 'results'
}).then(function (data) {
var feature = data.features[0];
var props = feature.properties;
content += "<h4>Flood Zone 3</h4><p>" + props.definition + "</p>";
});
}
if ($.inArray('layer63', displayedLayers) > -1) {
var url = layer63
.getSource()
.getGetFeatureInfoUrl(
evt.coordinate,
map.getView().getResolution(),
map.getView().getProjection(),
{
'INFO_FORMAT': 'text/javascript',
'format_options': 'callback:results',
'propertyName': 'definition'
}
);
reqwest({
url: url,
type: 'jsonp',
jsonpCallbackName: 'results'
}).then(function (data) {
var feature = data.features[0];
var props = feature.properties;
content += "<h4>Flood Zone 2</h4><p>" + props.definition + "</p>";
});
}
return content;
popup.show(evt.coordinate, content);
});
EDITED original answer as it wasn't correct, this one seems to work. It's jus a test based in your code but changes the way the popup is handled:
var layers = [
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://demo.opengeo.org/geoserver/wms?',
params: {
'LAYERS': 'ne:ne',
'TILED': true,
'version': '1.1.0'
},
serverType: 'geoserver',
})
}),
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://demo.opengeo.org/geoserver/wms?',
params: {
'LAYERS': 'ne:ne',
'TILED': true,
'version': '1.1.0'
},
serverType: 'geoserver',
})
})
];
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var popup = new ol.Overlay( /** #type {olx.OverlayOptions} */ ({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
}));
var map = new ol.Map({
layers: layers,
target: 'map',
overlays: [popup],
view: new ol.View({
center: [327641, 4149464],
zoom: 3,
//EPSG: 25830
})
});
map.on('singleclick', function (evt) {
content.innerHTML = "";
var displayedLayers = [];
var responses = 0;
var url = layers[0].getSource()
.getGetFeatureInfoUrl(
evt.coordinate,
map.getView().getResolution(),
map.getView().getProjection(), {
'INFO_FORMAT': 'text/javascript',
'format_options': 'callback:parseResponse',
'propertyName': 'name'
});
reqwest({
url: url,
type: 'jsonp',
jsonpCallbackName: 'parseResponse'
}).then(function (data) {
var feature = data.features[0];
var props = feature.properties;
content.innerHTML += "<h4>First Layer</h4><p>" + props.name + "</p>";
popup.setPosition(evt.coordinate);
});
// Second layer
var url = layers[1].getSource()
.getGetFeatureInfoUrl(
evt.coordinate,
map.getView().getResolution(),
map.getView().getProjection(), {
'INFO_FORMAT': 'text/javascript',
'format_options': 'callback:parseResponse',
'propertyName': 'name'
});
reqwest({
url: url,
type: 'jsonp',
jsonpCallbackName: 'parseResponse'
}).then(function (data) {
var feature = data.features[0];
var props = feature.properties;
content.innerHTML += "<h4>Second layer</h4><p>" + props.name + "</p>";
popup.setPosition(evt.coordinate);
});
});
Jsfiddle here: http://jsfiddle.net/fbma/1pchmpoo
for anyone struggling with openlayers 3+ getGetFeatureInfoUrl function with multiple layers, the solution for me was passing the parameters LAYERS, QUERY_LAYERS and FEATURE_COUNT. Specially the last one as even including all layers in the two former ones, geoserver indeed takes all the layers BUT assumes tha FEATURE_COUNT is 1
So the nex example did the work
var url = layers[0].getSource()
.getGetFeatureInfoUrl(
evt.coordinate,
map.getView().getResolution(),
map.getView().getProjection(), {
**'LAYERS':'ne:ne,ne:ne2,ne:ne3,ne:ne4,ne:ne5',
'QUERY_LAYERS': 'ne:ne,ne:ne2,ne:ne3,ne:ne4,ne:ne5',
'FEATURE_COUNT':100000**,
'INFO_FORMAT': 'text/javascript',
'format_options': 'callback:parseResponse',
'propertyName': 'name'
});
I want to create a function to simplify configuration of jQuery UI AutoComplete. Here is my function code:
(function($) {
$.fn.myAutocomplete = function() {
var cache = {};
var dataUrl = args.dataUrl;
var dataSend = args.dataItem;
$.autocomplete({
source: function(request, response) {
if (cache.term == request.term && cache.content) {
response(cache.content);
}
if (new RegExp(cache.term).test(request.term) && cache.content && cache.content.length < 13) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(cache.content, function(value) {
return matcher.test(value.value)
}));
}
$.ajax({
url: dataUrl,
dataType: "json",
type: "POST",
data: dataSend,
success: function(data) {
cache.term = request.term;
cache.content = data;
response(data);
}
});
},
minLength: 2,
});
}
}) (jQuery);
but when I'm using this function like:
$("input#tag").myAutocomplete({
dataUrl: "/auto_complete/tag",
dataSend: { term: request.term, category: $("input#category").val() }
});
It's give me an error:
Uncaught ReferenceError: request is not defined
Perhaps the error is referring to request.term in
$("input#tag").myAutocomplete({
dataUrl: "/auto_complete/tag",
dataSend: { term: request.term, category: $("input#category").val() }
});
Sorry for the trouble, I'm not adept at using jquery. Here's the final working code.
(function($) {
$.fn.myAutocomplete = function(opt) {
var cache = {};
this.autocomplete({
source: function(request, response) {
if (cache.term == request.term && cache.content) {
response(cache.content);
}
if (new RegExp(cache.term).test(request.term) && cache.content && cache.content.length < 13) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(cache.content, function(value) {
return matcher.test(value.value)
}));
}
opt.dataSend.term = request.term;
$.ajax({
url: opt.dataUrl,
dataType: "json",
type: "POST",
data: opt.dataSend,
success: function(data) {
cache.term = request.term;
cache.content = data;
response(data);
}
});
},
minLength: 2,
});
return this;
}
}) (jQuery);
To use this function just write code like this:
$("input#tag").myAutocomplete({
dataUrl: "/auto_complete/tag",
dataSend: { category: $("input#category").val() }
});
Thanks Jeffery To for sharing with me to solve this problem.. ^_^