Openlayers show markers after retrieving with Ajax - ajax

I have this code that shows the map, and I also get the marker points in the Ajax call.
It seems that it generates the map before the Ajax returns success. and I can't figure out how to update the map when the Ajax call return success.
Should I move everything but the Ajax call into a function which I call on Ajax success?
var jsonData = '';
let userData = null;
$.ajax({
url : "getBackyards.php",
type: "POST",
cache: false,
data:{id:"1"},
success:function(result){
console.log(result);
var stringified = JSON.stringify(result);
console.log(jsonData);
jsonData = JSON.parse(stringified);
console.log(jsonData);
},
});
/*
var jsonData =
{
"odessa": {
"title": "Odessa Restaurant, Kyiv",
"long": 30.5191,
"lat": 50.4227,
"imgSrc": "https://media-cdn.tripadvisor.com/media/photo-s/04/49/ca/08/odessa-restaurant.jpg",
"url": "https://odessarest.com.ua"
},
"example": {
"title": "Example marker",
"long": 31.5191,
"lat": 51.4227,
"imgSrc": "https://images-na.ssl-images-amazon.com/images/I/61PcbNuRRfL._SX425_.jpg",
"url": "https://mobiletechtracker.co.uk/"
}
};
*/
var modal = document.getElementById("myModal");
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
closeModal();
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal)
closeModal();
}
function closeModal() {
modal.style.display = "none";
}
function createStyle(src, img) {
return new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 0.96],
crossOrigin: 'anonymous',
src: src,
img: img,
imgSize: img ? [img.width, img.height] : undefined
}))
});
}
var iconFeatures = [];
setIconFeatures();
function setIconFeatures() {
for(var key in jsonData) {
var jsonItem = jsonData[key];
var iconFeature = new ol.Feature(new ol.geom.Point(ol.proj.fromLonLat([jsonItem.long, jsonItem.lat])));
iconFeature.setId(key);
iconFeature.set('style', createStyle('http://test.brugminbaghave.dk/img/BMB-logo.svg', undefined));
iconFeatures.push(iconFeature);
}
}
var distance = document.getElementById('distance');
var source = new ol.source.Vector({features: iconFeatures});
var unclusteredLayer = new ol.layer.Vector({
source: source,
style: function(feature) {
return feature.get('style');
},
maxResolution: 2000
});
var clusterSource = new ol.source.Cluster({
distance: parseInt(distance.value, 10),
source: source
});
var styleCache = {};
var clusters = new ol.layer.Vector({
source: clusterSource,
style: function(feature) {
var size = feature.get('features').length;
var style = styleCache[size];
if (!style) {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
});
styleCache[size] = style;
}
return style;
},
minResolution: 2001
});
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var map = new ol.Map({
target: 'map',
layers: [raster, clusters, unclusteredLayer],
view: new ol.View({
center: ol.proj.fromLonLat([9.5191, 55.4227]),
zoom: 6
})
});
distance.addEventListener('input', function() {
clusterSource.setDistance(parseInt(distance.value, 10));
});
map.on('click', function(event) {
map.forEachFeatureAtPixel(event.pixel, function(feature,layer) {
var key = feature.getId();
if (key in jsonData) {
var jsonItem = jsonData[key];
document.getElementById("modalTitle").innerText = jsonItem.title;
document.getElementById("modalImage").src = jsonItem.imgSrc;
document.getElementById("modalUrl").href = jsonItem.url;
modal.style.display = "block";
}
else if (map.getView().getZoom() < 7) {
map.getView().fit(feature.getGeometry(), {padding: [170, 50, 30, 150], minResolution: 1000});
}
});
});
map.on('pointermove', function(evt) {
map.getTargetElement().style.cursor =
map.hasFeatureAtPixel(evt.pixel) ? 'pointer' : '';
});

You could move everything, but as a minimum you need need to move the setIconFeatures call to the ajax callback, and then add the features to the source instead of creating the source with the features
var jsonData = '';
let userData = null;
var iconFeatures = [];
var source = new ol.source.Vector();
$.ajax({
url : "getBackyards.php",
type: "POST",
cache: false,
data:{id:"1"},
success:function(result){
console.log(result);
var stringified = JSON.stringify(result);
console.log(jsonData);
jsonData = JSON.parse(stringified);
console.log(jsonData);
setIconFeatures();
source.addFeatures(iconFeatures);
},
});
/*
var jsonData =
{
"odessa": {
"title": "Odessa Restaurant, Kyiv",
"long": 30.5191,
"lat": 50.4227,
"imgSrc": "https://media-cdn.tripadvisor.com/media/photo-s/04/49/ca/08/odessa-restaurant.jpg",
"url": "https://odessarest.com.ua"
},
"example": {
"title": "Example marker",
"long": 31.5191,
"lat": 51.4227,
"imgSrc": "https://images-na.ssl-images-amazon.com/images/I/61PcbNuRRfL._SX425_.jpg",
"url": "https://mobiletechtracker.co.uk/"
}
};
*/
var modal = document.getElementById("myModal");
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
closeModal();
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal)
closeModal();
}
function closeModal() {
modal.style.display = "none";
}
function createStyle(src, img) {
return new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 0.96],
crossOrigin: 'anonymous',
src: src,
img: img,
imgSize: img ? [img.width, img.height] : undefined
}))
});
}
function setIconFeatures() {
for(var key in jsonData) {
var jsonItem = jsonData[key];
var iconFeature = new ol.Feature(new ol.geom.Point(ol.proj.fromLonLat([jsonItem.long, jsonItem.lat])));
iconFeature.setId(key);
iconFeature.set('style', createStyle('http://test.brugminbaghave.dk/img/BMB-logo.svg', undefined));
iconFeatures.push(iconFeature);
}
}
var distance = document.getElementById('distance');
var unclusteredLayer = new ol.layer.Vector({
source: source,
style: function(feature) {
return feature.get('style');
},
maxResolution: 2000
});
var clusterSource = new ol.source.Cluster({
distance: parseInt(distance.value, 10),
source: source
});
var styleCache = {};
var clusters = new ol.layer.Vector({
source: clusterSource,
style: function(feature) {
var size = feature.get('features').length;
var style = styleCache[size];
if (!style) {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
});
styleCache[size] = style;
}
return style;
},
minResolution: 2001
});
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var map = new ol.Map({
target: 'map',
layers: [raster, clusters, unclusteredLayer],
view: new ol.View({
center: ol.proj.fromLonLat([9.5191, 55.4227]),
zoom: 6
})
});
distance.addEventListener('input', function() {
clusterSource.setDistance(parseInt(distance.value, 10));
});

Related

Google maps click event not working for clicking on markers

After a long research, I can't get the Google Maps on Click event work.
Here is my code;
function initialize_<?= $id; ?>() {
google.maps.visualRefresh = true;
var bounds = new google.maps.LatLngBounds();
var infowindow = new google.maps.InfoWindow({
content: '<h1>Test window</h1>'
});
var lat = <?php echo $lat ; ?>;
var lng = <?php echo $lng ; ?>;
var marker = new Array();
var options = {
zoom: 13,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.RIGHT_TOP
},
disableDoubleClickZoom: false,
draggable: true,
scrollwheel: false,
mapTypeControl: true,
mapTypeControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
},
mapTypeId: google.maps.MapTypeId.ROADMAP
}
if(lat && lng) {
var lat_lng = new google.maps.LatLng(lat, lng);
options.center = lat_lng;
}
var map = new google.maps.Map(document.getElementById('<?= $id; ?>'), options);
<?php
$markerIcon = get_field('marker_icon', 'option');
if($markerIcon) :
?>
var markerIcon = {
url: '<?= $markerIcon['url']; ?>',
size: new google.maps.Size(30, 40),
scaledSize: new google.maps.Size(30, 40),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(15, 40)
};
<?php endif; ?>
if(lat_lng) {
var marker = new google.maps.Marker({
position: lat_lng,
icon: (markerIcon ? markerIcon : '')
});
marker.setMap(map);
} else if(locations.length) {
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var bounds = new google.maps.LatLngBounds();
var markers = locations.map(function(location, i) {
var position = new google.maps.LatLng(location[0], location[1]);
bounds.extend(position);
var shape = {
coords: [],
type: 'poly'
};
var marker = new google.maps.Marker({
position: position,
icon: (markerIcon ? markerIcon : ''),
shape: shape,
label: labels[i % labels.length]
});
google.maps.event.addListener(marker, 'click', function() {
console.log('test');
});
return marker;
});
const markerClusterIcon = color => window.btoa(`
<svg fill="${color}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240">
<circle cx="120" cy="120" opacity="1" r="100" />
</svg>`);
new MarkerClusterer(map, markers, {
styles: [`black`].map(color => ({
url: `data:image/svg+xml;base64,${markerClusterIcon(color)}`,
height: 40,
width: 40,
textColor: `white`,
fontFamily: `'Playfair Display', serif`,
textSize: 16
})),
});
map.fitBounds(bounds);
}
}
google.maps.event.addDomListener(window, 'load', initialize_<?= $id; ?>);
I tried so many things. For now I've set a console log for the on click but it won't work. Does anybody know what the problem is?
I'm mapping the locations variable and in that function, I decided to add a listener for the click event.
Thanks for your help!
I removed shape: shape, from the marker variable and the info window is now showing up.

Related lat,lng using javascript

<script>
/* Edit */
function initialize()
{
var latlng = new google.maps.LatLng(51.165691,10.451526000000058);
var map = new google.maps.Map(document.getElementById('map'), {
center: latlng,
zoom: 13
});
var marker = new google.maps.Marker({
map: map,
position: latlng,
draggable: true,
anchorPoint: new google.maps.Point(0, -29)
});
var input = document.getElementById('searchInput');
// map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var geocoder = new google.maps.Geocoder();
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
autocomplete.addListener('place_changed', function() {
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
window.alert("Autocomplete's returned place contains no geometry");
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
marker.setPosition(place.geometry.location);
marker.setVisible(true);
alert('Edit=' +place.formatted_address);
bindDataToForm(place.formatted_address,place.geometry.location.lat(),place.geometry.location.lng());
infowindow.setContent(place.formatted_address);
infowindow.open(map, marker);
});
// this function will work on marker move event into map
google.maps.event.addListener(marker, 'dragend', function() {
geocoder.geocode({'latLng': marker.getPosition()}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
bindDataToForm(results[0].formatted_address,marker.getPosition().lat(),marker.getPosition().lng());
infowindow.setContent(results[0].formatted_address);
infowindow.open(map, marker);
}
}
});
});
}
function bindDataToForm(address,lat,lng){
document.getElementById('location').value = address;
document.getElementById('lat').value = lat;
document.getElementById('lng').value = lng;
alert('Edit'+lng);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<script>

Nativescript - How to POST Image with http.request

Help, I need call the http.request for send Image captured in camera api in my NativeScript App.
I capture the photo in camera api for nativescript and need send to api in upload process.
Follow the code about this process:
var frameModule = require("ui/frame");
var viewModule = require("ui/core/view");
var Observable = require("data/observable").Observable;
var config = require("../../shared/config");
var cameraModule = require("camera");
var imageModule = require("ui/image");
var http = require("http");
exports.loaded = function(args) {
var page = args.object;
viewModel = new Observable({
coleta: config.id_coleta
});
page.bindingContext = viewModel;
};
exports.voltar = function() {
var topmost = frameModule.topmost();
topmost.navigate("views/ocorrencia/menuocorrencia");
};
function tapFoto() {
cameraModule.takePicture({
width: 300,
height: 300,
keepAspectRatio: true
}).then(function(picture) {
var image = new imageModule.Image();
image.imageSource = picture;
var item = {
itemImage: picture
};
var urlfoto = "http://192.1.1.1:8090/sendphoto/upload";
alert("URL: " + urlfoto);
http.request({
url: urlfoto,
method: "POST",
headers: {
"Content-Type": "multipart/form-data"
},
content: ({uploadFile: image.imageSource, entrega: config.id_coleta})
}).then(function (response) {
var statusCode = response.statusCode;
alert("Codigo Retorno: " + statusCode);
alert("Foto registrada com sucesso.");
}, function (e){
alert("Erro: " + e);
});
});
}
exports.tapFoto = tapFoto;
I recommend using of nativescript-background-http plugin for uploading files.
tns plugin add nativescript-background-http
Here is your code modifed to work with the installed plugin:
"use strict";
var Observable = require("data/observable").Observable;
var cameraModule = require("camera");
var fs = require("file-system");
var bghttpModule = require("nativescript-background-http");
var session = bghttpModule.session("image-upload");
var viewModel = new Observable();
function navigatingTo(args) {
var page = args.object;
page.bindingContext = viewModel;
}
exports.navigatingTo = navigatingTo;
function onTap() {
cameraModule.takePicture({
width: 300,
height: 300,
keepAspectRatio: true
}).then(function (imageSource) {
console.log("Image taken!");
var folder = fs.knownFolders.documents();
var path = fs.path.join(folder.path, "Test.png");
var saved = imageSource.saveToFile(path, "png");
var request = {
url: "http://httpbin.org/post",
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
"File-Name": "Test.png"
},
description: "{ 'uploading': " + "Test.png" + " }"
};
var task = session.uploadFile(path, request);
task.on("progress", logEvent);
task.on("error", logEvent);
task.on("complete", logEvent);
function logEvent(e) {
console.log("----------------");
console.log('Status: ' + e.eventName);
// console.log(e.object);
if (e.totalBytes !== undefined) {
console.log('current bytes transfered: ' + e.currentBytes);
console.log('Total bytes to transfer: ' + e.totalBytes);
}
}
});
}
exports.onTap = onTap;

Simile Timeline - Events present but not displaying

I am working on a site that uses the Simile Timeline. I am using Kendo Core for the single page application components. I am loading the timeline from the results of an ajax request. I am manually adding the events. When I check the console the events are populated on the event source. However events do not display.
What do I need to change to get the events to display on the timeline?
Thanks in advance.
///////////////////////////////
// Timeline
///////////////////////////////
var timelineViewModel = kendo.observable({
InitUI: function (id) {
var self = this;
$.ajax({
url: "api/timelines/" + id,
type: "GET",
dataType: "json",
contentType: "application/json",
success: function (data) {
self.loadTimeLine(data);
}
});
},
loadTimeLine: function (data) {
SimileAjax.History.enabled = false;
$('#TimelineTitle').text(data.title);
var tl_el = document.getElementById("my-timeline");
var eventSource1 = new Timeline.DefaultEventSource();
for(var eIndex = 0; eIndex < data.events.length; eIndex ++)
{
var evt = new Timeline.DefaultEventSource.Event({
title: data.events[eIndex].title,
start: data.events[eIndex].start,
description: data.events[eIndex].description,
caption: data.events[eIndex].title,
color: '#FFCC33',
text: data.events[eIndex].title
});
eventSource1._events.add(evt);
}
var theme1 = Timeline.ClassicTheme.create();
theme1.event.bubble.width = 320;
theme1.event.bubble.height = 220;
var d = data.MinDate;
var bandInfos = [
Timeline.createBandInfo({
width: 100, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.YEAR,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'overview'
}),
Timeline.createBandInfo({
width: 100, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.MONTH,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'overview'
}),
Timeline.createBandInfo({
width: 350, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.WEEK,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'original'
})
];
bandInfos[1].syncWith = 2;
bandInfos[1].highlight = true;
bandInfos[0].syncWith = 2;
bandInfos[0].highlight = true;
tl = Timeline.create(tl_el, bandInfos, Timeline.VERTICAL);
tl.layout();
}
})
var timelineView = new kendo.View(
"timelineTemplate",
{
model: timelineViewModel
}
);
///////////////////////////////
// Layout
///////////////////////////////
var layout = new kendo.Layout("<div id='content'></div>");
///////////////////////////////
// DAS ROUTER
///////////////////////////////
var router = new kendo.Router();
router.route("(:viewName)/(:id)", function (viewName, id) {
layout.render("#maincontent");
if (viewName) {
switch (viewName.toLowerCase()) {
case "timeline":
if (id) {
if (id.toLowerCase() == "new") {
layout.showIn("#content", createTimelineView);
createTimelineViewModel.InitUI();
}
else {
layout.showIn("#content", timelineView);
timelineViewModel.InitUI(id);
}
}
break;
case "account":
if (id) {
layout.showIn("#content", accountView);
accountViewModel.InitUI(id);
}
break;
}
}
else {
layout.showIn("#content", indexView);
indexViewModel.InitUI();
}
});
$(function () {
router.start();
});

Image on popup window in google maps v3 api?

How I can put an image on a popup window when I click on a marker (bondi beach) in google maps v3 ? :
Here the code :
var locations = [
// Here I would put the Image ['Bondi Beach', -33.890542, 151.274856, 4],
];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
center: new google.maps.LatLng(46.713251, 7.833252),
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
map.setOptions({styles: styles});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
Try this :
<div id="map" style="width:500px;height:500px;"></div>
script :
var locations = [
['Bondi Beach', -33.890542, 151.274856, 'http://www.destination360.com/australia-south-pacific/australia/images/s/australia-bondi-beach.jpg'],
/*
add more locations here on the form :
[ name, lat, long, img ]
[ name, lat, long, img ]
..
*/
];
function initialize() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
center: new google.maps.LatLng(-33.890542, 151.274856),
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
var content=locations[i][0]+'<br><img src="'+locations[i][3]+'" style="width:300px;">';
infowindow.setContent(content);
infowindow.open(map, marker);
}
})(marker, i));
}
}
google.maps.event.addDomListener(window, 'load', initialize);
DEMO
result :

Resources