I'm building a Google Map where I have 20-40 points plotted. Currently, when you hover over a point it triggers a qTip popup. I wrote a script to change the "panto" every 6 seconds and I'm trying to trigger the corresponding qTip when the point panned on.
<script type="text/javascript">
var map, marker, latLngToPixel;
var locations = [
["Reforestation Cumberland State Forest", 37.4963918, -78.2448664, "", "www.dof.virginia.gov"],
["Guaranta Settlement, Brazil ", -13.44234, -47.944336, "Brazil", "guaranta-settlement-brazil"],
["Trees For Cameroon", 7.369722, 12.354722, "Cameroon", "trees-for-cameroon"],
["Trees for Colombia", 6.3166667, -76.1333333, "Colombia", "urrao-colombia-trees-for-the-future"],
["Trees Water and People Trees for Food Project", 14.0200366, -89.6451688, "El Salvador", ""],
["Trees For Ethiopia", 8.4, 38.4, "Ethiopia", "trees-for-ethiopia"],
["Trees For Ghana", 7.946527, -1.023194, "Ghana", "trees-for-ghana"],
["Trees for Haiti", 18.7703377, -72.513088, "Haiti", "trees-for-haiti"],
["Trees For India", 11.1271225, 78.6568942, "India", "trees-for-india"],
["Madagascar Mangrove Rehabilitation", -23.6682, 46.13353, "Madagascar", "madagascar-mangrove-rehabilitation"],
["Trees For Mali", 12.39495, -7.937085, "Mali", "trees-for-mali"],
["Las Mercedes Reforestation", 13.4726005, -86.4592091, "Nicaragua", ""],
["Trees For Senegal", 14.10686, -15.55198, "Senegal", "trees-for-senegal"],
["Trees for Tanzania ", -8.588228, 35.29755, "Tanzania", "trees-for-tanzania-"],
["Trees for Uganda", 1.2124107, 33.7804036, "Uganda", "trees-for-uganda"],
["Reforest Kentucky", 38.2009055, -84.8732835, "United States", "reforest-kentucky"],
["Celebrate Arbor Day", 40.0583238, -74.4056612, "United States", ""],
["Longleaf Pine Reforestation Project", 32.1574351, -82.907123, "United States", "longleaf-pine-reforestation-on-georgia-state"],
["Trees for Tributaries", 43.0484029, -75.3785034, "United States", "trees-for-tributaries"],
["Wisconsin State Lands Tree Planting", 43.7844397, -88.7878678, "United States", "wisconsin-state-lands-tree-planting"],
["Flight 93 Memorial Reforestation Project", 40.0178571, -78.9072458, "United States", "Flight-93-Memorial-Reforestation"],
["Michigan State Forest Reforestation", 44.5105121, -85.5145764, "United States", "michigan-state-forest-reforestation"],
["Bladen Lakes State Forest", 35.80728455266026, -79.4805908203125, "United States", "bladen-lakes-state-forest"],
["Green Forests Work Maryland", 39.45316112807393, -77.97875979915261, "United States", "www.greenforestswork.org"],
["Green Forests Work Ohio", 39.010648, -83.469727, "United States", "www.greenforestswork.org"],
["Green Forests Work West Virginia", 39.01918382053526, -80.56054690852761, "United States", "www.greenforestswork.org"],
["Green Forests Work Alabama", 34.08906131584996, -86.83154303580523, "United States", "www.greenforestswork.org"],
["Green Forests Work Tennessee", 35.022799223730146, -86.50195319205523, "United States", "www.greenforestswork.org"],
];
function initialize() {
var styles = [ { featureType: "administrative.locality", stylers: [ { visibility: "simplified" } ] }, { featureType: "road.highway", stylers: [ { visibility: "off" } ] }, { featureType: "water", stylers: [ { visibility: "simplified" } ] }, { featureType: "administrative.locality", stylers: [ { visibility: "off" } ] }, { featureType: "water", stylers: [ { visibility: "on" }, { hue: "#85c6dc" } ] } ];
var CENTER_EARTH = new google.maps.LatLng(38, 0);
elem = document.getElementById('map_canvas');
var mapOptions = {
zoom: 2,
center: CENTER_EARTH
};
function LatLngToPixel(map) { this.setMap(map); }
LatLngToPixel.prototype = new google.maps.OverlayView();
LatLngToPixel.prototype.draw = function() {}
map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
var build = new google.maps.StyledMapType(styles, mapOptions);
var infowindow = new google.maps.InfoWindow();
var marker, i;
var id = 1;
map.mapTypes.set('map', build);
map.setMapTypeId('map');
latLngToPixel = new LatLngToPixel(map);
/* Loop Through To Generate Points, Left 1 For Example... */
generateMarker(id, 37.4963918, -78.2448664, "Reforestation Cumberland ...", "Cumberland, Virginia ", "www.dof.virginia.gov", "61", "0", "61_4f0312528dbf4VA 4.jpg" );
id++;
}
function generateMarker(id, Lat, Lng, ProjectName, Location, PURL, idProject, TreesPlanted, Thumb) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(Lat, Lng),
icon: 'http://staging.&********.com/css/images/pin.png',
map: map,
});
var content = '<img style="float:left;margin-right:10px;" src="../common/perfectimg.php?w=61&h=62&u=/common/assets/'+Thumb+'&x=y.jpg" alt="tooltip1" width="61" height="62" /><div style="float:left;"><strong>' + ProjectName + '</strong><br />' + TreesPlanted + ' Trees Planted So Far... <br />' + Location + "</div>";
google.maps.event.addDomListener(marker, 'mouseover', function(event) {
var pixel = latLngToPixel.getProjection().fromLatLngToContainerPixel(event.latLng);
var pos = [ pixel.x, pixel.y ];
marker.tooltip = $('<div />').qtip({
content: content,
width: 600,
style: {
classes: 'ui-tooltip-blue',
tip: {
width: 12,
height: 12
}
},
position: {
my: 'bottom center',
at: 'left center',
adjust: {
x:-5, y:-32
},
target: pos,
container: $('#map_canvas'),
viewport: $('.map')
},
show: {
ready: true,
event: false,
solo: true
},
hide: {
event: 'mouseleave unfocus'
}
})
.qtip('api');
});
google.maps.event.addListener(marker, 'click', function(event) {
window.location = "?idProject="+idProject;
});
}
$(document).ready(function() {
initialize();
var x = 0;
setInterval(function(){
if(x > locations.length) x = 0;
map.setZoom(5);
map.panTo(new google.maps.LatLng(locations[x][1],locations[x][2]));
x++;
}, 6000);
});
</script>
I would say add your markers into an array as you add them. Then when you call your panTo, also trigger a click on that marker.
Create a global variable called arrMarkers. Then at the end of generateMarker function:
arrMarkers.push(marker);
Then in your setInterval function:
map.panTo(new google.maps.LatLng(locations[x][1],locations[x][2]));
google.maps.event.trigger(arrMarkers[x], 'click');
In fact, you may even be able to remove the panTo itself, as triggering the click will I think pan the map automatically anyway!
PS: The trailing comma at the end of the very last item in your array here will cause problems in IE (although this maybe isn't the actual data you're using):
["Green Forests Work Tennessee", 35.022799223730146, -86.50195319205523, "United States", "www.greenforestswork.org"],
Related
I've done a mapping before, but not this deeply nested. I am trying to re-populate data from a corrupt db. I have manually reconstructed an orders array. I'm trying to look up data for each player, and then update the fields (which start out null) for each player:
Example: I start with data like this:
const orders = [
{
"paymentID": "ch_456",
"paymentStatus": "PAID",
"user": "kingkong#gmail.com",
"cart": {
"username": "kingkong#gmail.com",
"totalQty": 1,
"totalPrice": 80,
"items": [{
"event": "Men's BB",
"division": "Men's",
"level": "BB",
"group": "nonpro",
"field": "PAL",
"day": "Saturday",
"numplayers": 2,
"price": 80,
"players": [{
"avp_id": 1042641,
"first": "King",
"last": "Kong",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false},
{
"avp_id": 1086117,
"first": "Jacob",
"last": "Ladder",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false,
"shirt_size": "N/A"}],
"net": null,
"team": null,
"notes": null,
"paymentNote": null,
"waiversSent": false,
"active": true,
"paymentID": "ch_456",
"users": ["kingkong#gmail.com"],
"paymentStatus": "PAID", "__v": 4}]},
"__v": 0
},{
"paymentID": "ch_123",
"paymentStatus": "PAID",
"user": "marymac#aol.com",
"cart": {
"username": "marymac#aol.com",
"totalQty": 1,
"totalPrice": 50,
"items": [{
"event": "Junior Boys 16s",
"division": "Junior Boys",
"level": "16s",
"group": "nonpro",
"field": "Main",
"day": "Friday",
"numplayers": 2,
"price": 80,
"players": [{
"avp_id": 1022228,
"first": "Some",
"last": "Kid",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false
}, {
"avp_id": 1020142,
"first": "Justin",
"last": "Kid",
"waivers": [],
"completed": true,
"country": "USA",
"signed": false,
"shirt_size": "N/A"
}
],
"net": null,
"team": null,
"notes": null,
"paymentNote": null,
"waiversSent": false,
"active": true,
"paymentID": "ch_123",
"users": ["marymac#aol.com"],
"paymentStatus": "PAID", "__v": 4
}
]
},
"__v": 0
}];
Here is my code, which I'd like to get the data from an API, and update player info to pass into a function further down:
async getLostData() {
// get the lost orders
console.log('start lost data import');
// this.adminService.GetLostOrders().subscribe(orders => {
// console.log('load each order into system', orders);
orders.forEach(order => {
order.cart.items.map(item => {
const players = item.players.map(async player => {
player = await
this.adminService.adminAVPReg(player.last, player.avp_id)
.toPromise();
console.log("updated player outside subscribe", player);
});
item.players = players;
console.log("item", item);
});
// load order with updated info, create registration, and skip pmt
// this.adminService.LoadLostOrders(order).subscribe(data => {
// console.log(data);
// console.log('finished');
// });
});
console.log("orderlist", orders);
// });}
The data I'm getting logged is interesting. What comes back first from the logger is each item, followed by orderlist, and then the updated player info. Each item shows the players array listed as ZoneAwarePromise. I have no idea how to replace that with the actual data, but I can see it's not being logged in the order I expected.
How can I get the item to return with the updated data?
From what I understood you are trying to do, I came up with this,
this.adminService.GetLostOrders().pipe(
mergeMap((orders: any[]) => from(orders).pipe(
mergeMap((order) => from(order.cart.items)),
mergeMap((item) => of(item).pipe(
mergeMap(_ => from(item.players)),
mergeMap(player => this.adminService.adminAVPReg(player.last, player.avp_id).pipe(
map(newPlayer => { player = newPlayer; return player; }))
),
toArray(),
tap(newPlayerArray => item.players = newPlayerArray)
)),
toArray(),
mergeMap(_ => this.adminService.LoadLostOrders(orders))
))
).subscribe();
OP's Edit
I implemented what you shared above, and turned it into this:
getLostData() {
// get the lost orders
console.log('start lost data import');
// get manually created orders from lostdata collection
this.adminService.GetLostOrders()
.pipe(
mergeMap((orders: any) => from(orders).pipe(
mergeMap((order: any) => from(order.cart.items)),
mergeMap((item: any) => of(item).pipe(
mergeMap(_ => from(item.players)),
mergeMap((player: any) => this.adminService.adminAVPReg(player.last, player.avp_id).pipe(
map((newPlayer: any) => {
player.avp_id = player.avp_id;
player.signed = player.signed;
player.waivers = player.waivers;
player.country = player.country;
player.completed = true;
player.sandbagger = false;
player.first = newPlayer.first;
player.last = newPlayer.last;
player.email = newPlayer.email;
player.address = newPlayer.address;
player.city = newPlayer.city;
player.state = newPlayer.state;
player.zip = newPlayer.zip;
player.shirt_size = newPlayer.shirt_size;
player.ranking = newPlayer.ranking;
player.overallRanking = newPlayer.overallRanking;
player.notes = player.notes;
player.phone = newPlayer.phone;
player.adult = newPlayer.adult;
return player; }))
),
toArray(),
tap(newPlayerArray => item.players = newPlayerArray)
)),
toArray(),
tap(_ => { this.loadlostOrders(orders);
})
))
)
.subscribe();
}
loadlostOrders(orders) {
orders.forEach(order => {
this.adminService.LoadLostOrders(order).subscribe((data) => {
console.log("success", JSON.stringify(data));
}, (error) => {
console.log("error", JSON.stringify(error));
});
});
}
I have the following data structure that I'm looking to transform. The structure exist as follows:
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"providers": [
{
"providerNumber": "157833AC",
"providerName": "DR TEST"
}
],
"serviceItems": [
{
"itemName": "INITIAL CONS",
"itemNumber": "100",
"fee": 0,
"isReferenceItem": "true",
"customisations": [
{
"practiceDisplayName": "First Assessment",
"fee": 50,
"isPracticeReferenceItem": "true"
}
]
},
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true",
"customisations": [
{
"practiceDisplayName": "Consult One",
"fee": 23.35,
"isPracticeReferenceItem": "true"
},
{
"practiceDisplayName": "Consult Two",
"fee": 15,
"isPracticeReferenceItem": "false"
}
]
}
]
}
]
}
I'm wanting a query that returns the id, practiceId and extrasCoverservices (serviceTypeName, serviceTypeCode and the serviceItems). I don't want to include the provider information.
I've tried this, but I need to specify the position of the element in the array which I don't want to do. Any help would be much appreciated.
SELECT a.id
, a.practiceId
, [{"serviceTypeName": a.extrasCoverServices[0].serviceTypeName, "serviceTypeCode": a.extrasCoverServices[0].serviceTypeCode, "serviceItems": a.extrasCoverServices[0].serviceItems}]
Update
function sample(documentId) {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT ARRAY_CONCAT([{"itemId": s.itemId, "itemName": s.itemName,"itemNumber":s.itemNumber,"fee":s.fee,"isReferenceItem":s.isReferenceItem}], IS_DEFINED(s.customisations) ? s.customisations : []) as extrasCoverServices FROM a JOIN e in a.extrasCoverServices JOIN s in e.serviceItems WHERE a.id =' + "'" + documentId + "'",
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
console.log(feed.length);
var result = feed.flatten(function(x) {
return x.extrasCoverServices;
});
getContext().getResponse().setBody(result);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
You almost had it. To achieve this, you can use features:
inner-document joining using join keyword
explicit JSON composition using { and } wrappers
The first gives you access to the subItem you want to cherry-pick and the second enables you to glue them back together they way you like it.
The query you are looking for should be along the lines of this:
SELECT
a.id,
a.practiceId,
[{
"serviceTypeName": e.serviceTypeName,
"serviceTypeCode" : e.serviceTypeCode,
"serviceItems": e.serviceItems
}] as extrasCoverServices
FROM a
join e in a.extrasCoverServices
Note that you can combine Sql-like select with explicit JSON building in the same query to keep the query more compact. Also, I suggest you use CosmosDB SQL query cheat sheet to easily discover, what's in the toolbox.
function sample(documentId, itemId) {
var collection = getContext().getCollection();
var query = 'SELECT e.serviceTypeCode, '+
' e.serviceTypeName, '+
' s.itemNumber, '+
' ARRAY_CONCAT( '+
' [{ '+
' "itemId": s.itemId, '+
' "itemName": s.itemName, '+
' "fee":s.fee, '+
' "isReferenceItem":s.isReferenceItem '+
' }], '+
' IS_DEFINED(s.customisations) ? s.customisations : []) as extrasCoverServices '+
' FROM a '+
' JOIN e in a.extrasCoverServices '+
' JOIN s in e.serviceItems '+
' WHERE a.id = ' + "'" + documentId + "'";
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
query,
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
var returnResult = [];
for(var i = 0; i<feed.length; i++) {
let serviceItem = feed[i];
let serviceItemsArray = feed[i].extrasCoverServices;
for(var j = 0; j < serviceItemsArray.length; j++) {
let item = serviceItemsArray[j];
let mapped = {
serviceTypeCode: serviceItem.serviceTypeCode
, serviceTypeName: serviceItem.serviceTypeName
, itemId: item.itemId
, itemName: (item.itemName ? item.itemName : item.practiceDisplayName)
, itemNumber: serviceItem.itemNumber
, fee: item.fee
, isReferenceItem: ((item.isReferenceItem && item.isReferenceItem == true) ? item.isReferenceItem: false)
, isPracticeReferenceItem: (item.isPracticeReferenceItem && item.isPracticeReferenceItem == true ? item.isPracticeReferenceItem : false)
};
returnResult.push(mapped);
}
}
if(itemId != undefined) {
var filteredReturnResult = returnResult.filter(r => r.itemId == itemId);
getContext().getResponse().setBody(filteredReturnResult);
return
}
getContext().getResponse().setBody(returnResult);
if (!isAccepted) throw new Error('The query was not accepted by the server.');
})
}
Please use sql like:
SELECT a.id,a.practiceId,e.serviceTypeName,e.serviceTypeCode,e.serviceItems
FROM a
join e in a.extrasCoverServices a
Result:
If you want to make the e.serviceTypeName,e.serviceTypeCode,e.serviceItems into an array, not parallel with id and praticeId, I suggest you using stored procedure in cosmos db.
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT c.id,c.practiceId,c.extrasCoverServices FROM root c',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
var returnResult = [];
for(var i = 0;i<feed.length;i++){
var obj1 = {
id:"",
practiceId:"",
serviceArray :[]
};
obj1.id = feed[i].id;
obj1.practiceId = feed[i].practiceId;
var loopArray = feed[i].extrasCoverServices;
var serviceResult = [];
for(var j = 0;j<loopArray.length;j++){
var obj2 = {
serviceTypeName:"",
serviceTypeCode:"",
serviceItems:[] };
obj2.serviceTypeName=loopArray[j].serviceTypeName;
obj2.serviceTypeCode=loopArray[j].serviceTypeCode;
obj2.serviceItems=loopArray[j].serviceItems;
serviceResult.push(obj2);
}
obj1.serviceArray= serviceResult;
returnResult.push(obj1);
}
getContext().getResponse().setBody(returnResult);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Result:
Hope it helps you.
Update Answer 1:
For your further requirement in your comment, I test a sql for you.
SELECT
a.id,
a.practiceId,
[{
"serviceTypeName": e.serviceTypeName,
"serviceTypeCode" : e.serviceTypeCode,
"serviceItems": [
{"itemName": s.itemName,
"itemNumber":s.itemNumber,
"fee":s.fee,
"isReferenceItem":s.isReferenceItem
},
{"practiceDisplayName":c.practiceDisplayName,
"itemNumber":s.itemNumber,
"fee": c.fee,
"isPracticeReferenceItem":c.isPracticeReferenceItem
}
]
}] as extrasCoverServices
FROM a
join e in a.extrasCoverServices
join s in e.serviceItems
join c in s.customisations
However , the results have multiple items because of the join.
[
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "INITIAL CONS",
"itemNumber": "100",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "First Assessment",
"itemNumber": "100",
"fee": 50,
"isPracticeReferenceItem": "true"
}
]
}
]
},
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "Consult One",
"itemNumber": "200",
"fee": 23.35,
"isPracticeReferenceItem": "true"
}
]
}
]
},
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "Consult Two",
"itemNumber": "200",
"fee": 15,
"isPracticeReferenceItem": "false"
}
]
}
]
}
]
So, I suggest you processing the results in the stored procedure to match your requirement.
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT a.id, a.practiceId,'+
'[{'+
'"serviceTypeName": e.serviceTypeName, '+
'"serviceTypeCode" : e.serviceTypeCode, '+
'"serviceItems": ['+
'{"itemName": s.itemName,'+
'"itemNumber":s.itemNumber,'+
'"fee":s.fee,'+
'"isReferenceItem":s.isReferenceItem'+
'},'+
'{"practiceDisplayName":c.practiceDisplayName,'+
'"itemNumber":s.itemNumber,'+
'"fee": c.fee,'+
'"isPracticeReferenceItem":c.isPracticeReferenceItem '+
'}'+
']'+
'}] as extrasCoverServices'+
' FROM a '+
' join e in a.extrasCoverServices'+
' join s in e.serviceItems'+
' join c in s.customisations',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
var returnResult = [];
var obj1 = {
id:"",
practiceId:"",
extrasCoverServices :[]
};
var temp = "";
for(var i = 0;i<feed.length;i++){
if(temp==feed[i].id){
var extrasArray = obj1.extrasCoverServices[0].serviceItems;
var serviceArray = feed[i].extrasCoverServices[0].serviceItems;
for(var j = 0;j<serviceArray.length;j++){
extrasArray.push(serviceArray[j]);
}
obj1.extrasCoverServices[0].serviceItems = extrasArray;
} else{
obj1.id = feed[i].id;
obj1.practiceId = feed[i].practiceId;
obj1.extrasCoverServices = feed[i].extrasCoverServices;
temp = feed[i].id;
}
}
returnResult.push(obj1);
getContext().getResponse().setBody(returnResult);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Process Result:
[
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "INITIAL CONS",
"itemNumber": "100",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "First Assessment",
"itemNumber": "100",
"fee": 50,
"isPracticeReferenceItem": "true"
},
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "Consult One",
"itemNumber": "200",
"fee": 23.35,
"isPracticeReferenceItem": "true"
},
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "Consult Two",
"itemNumber": "200",
"fee": 15,
"isPracticeReferenceItem": "false"
}
]
}
]
}
]
Update Answer 2:
Well,I still focus on implementing your needs through the Stored Procedure.
I add one item without customisations array into serviceItems as below:
[
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "INITIAL CONS",
"itemNumber": "100",
"fee": 0,
"isReferenceItem": "true",
"customisations": [
{
"practiceDisplayName": "First Assessment",
"fee": 50,
"isPracticeReferenceItem": "true"
}
]
},
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true",
"customisations": [
{
"practiceDisplayName": "Consult One",
"fee": 23.35,
"isPracticeReferenceItem": "true"
},
{
"practiceDisplayName": "Consult Two",
"fee": 15,
"isPracticeReferenceItem": "false"
}
]
},
{
"itemName": "FOR TEST",
"itemNumber": "333",
"fee": 20,
"isReferenceItem": "true"
}
]
}
]
}
]
SP CODE:
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT a.id, a.practiceId,'+
'[{'+
'"serviceTypeName": e.serviceTypeName, '+
'"serviceTypeCode" : e.serviceTypeCode, '+
'"serviceItems": e.serviceItems'+
'}] as extrasCoverServices'+
' FROM a '+
' join e in a.extrasCoverServices',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
for(var i = 0;i<feed.length;i++){
var extraArray = feed[i].extrasCoverServices;
for(var j = 0;j<extraArray.length;j++){
var serviceArray = extraArray[j].serviceItems;
var array = [];
for(var k = 0;k<serviceArray.length;k++){
var o1 = {
"itemName": "",
"itemNumber":"",
"fee" : "",
"isReferenceItem":""
};
console.log(k+"----");
o1.itemName = serviceArray[k].itemName;
o1.itemNumber = serviceArray[k].itemNumber;
o1.fee = serviceArray[k].fee;
o1.isReferenceItem = serviceArray[k].isReferenceItem;
console.log(o1.itemName);
array.push(o1);
if(null != serviceArray[k].customisations){
var customisationsArray = serviceArray[k].customisations;
for(var p = 0;p<customisationsArray.length;p++){
var o2 = {
"practiceDisplayName": "",
"itemNumber":"",
"fee" : "",
"isPracticeReferenceItem":""
};
o2.practiceDisplayName = customisationsArray[p].practiceDisplayName;
o2.itemNumber = o1.itemNumber;
o2.fee = customisationsArray[p].fee;
o2.isPracticeReferenceItem = customisationsArray[p].isPracticeReferenceItem;
array.push(o2);
}
}
}
feed[i].extrasCoverServices[j].serviceItems = array;
}
}
getContext().getResponse().setBody(feed);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Just for summary, I tidied up your last SP code. This is a good thread.
function sample(documentId, itemId) {
var collection = getContext().getCollection();
var query = 'SELECT e.serviceTypeCode, '+
' e.serviceTypeName, '+
' s.itemNumber, '+
' ARRAY_CONCAT( '+
' [{ '+
' "itemId": s.itemId, '+
' "itemName": s.itemName, '+
' "fee":s.fee, '+
' "isReferenceItem":s.isReferenceItem '+
' }], '+
' IS_DEFINED(s.customisations) ? s.customisations : []) as extrasCoverServices '+
' FROM a '+
' JOIN e in a.extrasCoverServices '+
' JOIN s in e.serviceItems '+
' WHERE a.id = ' + "'" + documentId + "'";
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
query,
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
var returnResult = [];
for(var i = 0; i<feed.length; i++) {
let serviceItem = feed[i];
let serviceItemsArray = feed[i].extrasCoverServices;
for(var j = 0; j < serviceItemsArray.length; j++) {
let item = serviceItemsArray[j];
let mapped = {
serviceTypeCode: serviceItem.serviceTypeCode
, serviceTypeName: serviceItem.serviceTypeName
, itemId: item.itemId
, itemName: (item.itemName ? item.itemName : item.practiceDisplayName)
, itemNumber: serviceItem.itemNumber
, fee: item.fee
, isReferenceItem: ((item.isReferenceItem && item.isReferenceItem == true) ? item.isReferenceItem: false)
, isPracticeReferenceItem: (item.isPracticeReferenceItem && item.isPracticeReferenceItem == true ? item.isPracticeReferenceItem : false)
};
returnResult.push(mapped);
}
}
if(itemId != undefined) {
var filteredReturnResult = returnResult.filter(r => r.itemId == itemId);
getContext().getResponse().setBody(filteredReturnResult);
return
}
getContext().getResponse().setBody(returnResult);
if (!isAccepted) throw new Error('The query was not accepted by the server.');
})
}
I have 2 google Maps on the same page. Each one have a set of different markers.
on the first map, when you clic a marker the infowindow shows, but on the second map the markers apear, but don't open the info window.
You can see in this page: http://www.qd1.com.br/maptest/
How can I solve it?
The code is here:
<h1>Map 1</h1>
<div id="map-sao-paulo" class="mapa-home"></div>
<h1>Map 2</h1>
<div id="map-jundiai" class="mapa-home"></div>
<style>
.mapa-home {
width: 100%;
height: 600px;
background-color: grey;
}
</style>
<script>
var urlPortfolio = 'http://www.qd1.com.br/maptest/';
var urlTema = 'http://www.qd1.com.br/maptest/';
/* MAP FUNCTIONS */
var locations = [
['Rua Oscar Caravelas', -23.544130, -46.694866, 'Rua Oscar Caravelas', 'futuro', 'Rua Oscar Caravelas, Vila Madalena, São Paulo, SP','rua-oscar-caravelas'],
['Residencial Tangará Pinheiros', -23.561472, -46.681912, 'Residencial Tangará Pinheiros', 'entregue', 'Rua Cônego Eugenio Leite nº 866, Pinheiros, São Paulo, SP','residencial-tangara-pinheiros'],
['Home Studio 47', -23.553518, -46.678283, 'Home Studio 47', 'lancamento', 'R. Capote Valente, 980 - Pinheiros São Paulo - SP','home-studio-47'],
['Edifício Praça dos Pinheiros', -23.541635, -46.704697, 'Edifício Praça dos Pinheiros', 'entregue', 'Rua Antonio Borba, 489 Vila Madalena, São Paulo, SP','edificio-praca-dos-pinheiros'],
['Ed. Hit Paulista', -23.563348, -46.643135, 'Ed. Hit Paulista', 'lancamento', 'Rua Arthur Prado, 341, Bela Vista, São Paulo, SP','hit-paulista'],
['Ed. Praça de Veneza', -23.545856, -46.696868, 'Ed. Praça de Veneza', 'entregue', 'Av. das Corujas, 584 Alto de Pinheiros, São Paulo, SP','ed-praca-de-veneza'],
]
var locations2 = [
['Av. Américo Bruno', -23.189918, -46.869183, 'Av. Américo Bruno', 'futuro', 'Av. Américo Bruno, Jundiaí, SP','jundiai-av-americo-bruno'],
['Av. Frederico Ozanon', -23.183679, -46.877656, 'Av. Frederico Ozanon', 'futuro', 'Av. Frederico Ozanon, Jundiaí, SP','jundiai-av-frederico-ozanon'],
['Casas Vila Malota', -23.215822, -46.910892, 'Casas Vila Malota', 'entregue', 'Rua dos Jequitibás 850, Malota, Jundiaí, SP','casas-vila-malota'],
]
var markers = new Array();
var markers2 = new Array();
var map;
var map2;
var estilos = [
{
"featureType": "water",
"elementType": "geometry",
"stylers": [
{
"color": "#aaaaaa"
},
{
"lightness": 17
}
]
},
{
"featureType": "landscape",
"elementType": "geometry",
"stylers": [
{
"color": "#dddddd"
},
{
"lightness": 20
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#ffffff"
},
{
"lightness": 17
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#ffffff"
},
{
"lightness": 29
},
{
"weight": 0.2
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry",
"stylers": [
{
"color": "#ffffff"
},
{
"lightness": 18
}
]
},
{
"featureType": "road.local",
"elementType": "geometry",
"stylers": [
{
"color": "#ffffff"
},
{
"lightness": 16
}
]
},
{
"featureType": "poi",
"elementType": "geometry",
"stylers": [
{
"color": "#f5f5f5"
},
{
"lightness": 21
}
]
},
{
"featureType": "poi.park",
"elementType": "geometry",
"stylers": [
{
"color": "#a7ce84"
},
{
"lightness": 21
}
]
},
{
"elementType": "labels.text.stroke",
"stylers": [
{
"visibility": "on"
},
{
"color": "#ffffff"
},
{
"lightness": 16
}
]
},
{
"elementType": "labels.text.fill",
"stylers": [
{
"saturation": 36
},
{
"color": "#333333"
},
{
"lightness": 40
}
]
},
{
"elementType": "labels.icon",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "transit",
"elementType": "geometry",
"stylers": [
{
"color": "#f1f1f1"
},
{
"lightness": 19
}
]
},
{
"featureType": "administrative",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#efefef"
},
{
"lightness": 20
}
]
},
{
"featureType": "administrative",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#efefef"
},
{
"lightness": 17
},
{
"weight": 1.2
}
]
}
];
var contentContainer = [];
var contentContainer2 = [];
function initialize() {
map = new google.maps.Map(document.getElementById('map-sao-paulo'), {
zoom: 14,
scrollwheel: false,
center: new google.maps.LatLng(-23.553518, -46.678283),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false,
panControl: false,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
},
styles: estilos
});
map2 = new google.maps.Map(document.getElementById('map-jundiai'), {
zoom: 14,
scrollwheel: false,
center: new google.maps.LatLng(-23.197818, -46.880150),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false,
panControl: false,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
},
styles: estilos
});
var infowindow = new google.maps.InfoWindow({
maxWidth: 350
});
var iconCounter = 0;
var iconCounter2 = 0;
// Add the markers and infowindows to the map
for (var i = 0; i < locations.length; i++) {
contentContainer.push('<div id="iw-container">'+locations[i][3]+'</div>');
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
url: urlPortfolio + locations[i][6],
icon: urlTema + 'images/map-marker-'+locations[i][4]+'.png',
title: 'Saiba mais'
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function(){
infowindow.setContent('' + locations[i][3] + '');
infowindow.open(map, marker);
var lat = marker.getPosition().lat();
var lng = marker.getPosition().lng();
var latlng = new google.maps.LatLng(lat, lng);
map.setCenter(latlng);
}
})(marker, i));
}
for (var i = 0; i < locations2.length; i++) {
contentContainer.push('<div id="iw-container">'+locations2[i][3]+'</div>');
var marker2 = new google.maps.Marker({
position: new google.maps.LatLng(locations2[i][1], locations2[i][2]),
map: map2,
url: urlPortfolio + locations2[i][6],
icon: urlTema + 'images/map-marker-'+locations2[i][4]+'.png',
title: 'Saiba mais'
});
markers.push(marker2);
google.maps.event.addListener(marker2, 'click', (function (marker2, i) {
return function(){
infowindow2.setContent('' + locations2[i][3] + '');
infowindow2.open(map2, marker2);
var lat2 = marker2.getPosition().lat();
var lng2 = marker2.getPosition().lng();
var latlng2 = new google.maps.LatLng(lat2, lng2);
map2.setCenter(latlng2);
}
})(marker2, i));
}
google.maps.event.addListener(infowindow, 'domready', function() {
var iwOuter = jQuery('#map-sao-paulo .gm-style-iw');
iwOuter.css({'margin-top' : '0px','font-weight' : 'bold'});
var iwBackground = iwOuter.prev();
iwBackground.children(':nth-child(4)').css({'background-color': '#fff','border': 'solid 1px #aaa'});
iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'display: none;'});
iwBackground.children(':nth-child(2)').attr('style', function(i,s){ return s + 'display: none;'});
iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'display: none;'});
});
google.maps.event.addListener(infowindow2, 'domready', function() {
var iwOuter2 = jQuery('#map-jundiai .gm-style-iw');
iwOuter2.css({'margin-top' : '0px','font-weight' : 'bold'});
var iwBackground2 = iwOuter2.prev();
iwBackground2.children(':nth-child(4)').css({'background-color': '#fff','border': 'solid 1px #aaa'});
iwBackground2.children(':nth-child(1)').attr('style', function(i,s){ return s + 'display: none;'});
iwBackground2.children(':nth-child(2)').attr('style', function(i,s){ return s + 'display: none;'});
iwBackground2.children(':nth-child(3)').attr('style', function(i,s){ return s + 'display: none;'});
});
autoCenter();
autoCenter2();
}
// function loadURL(marker) {
// return function () {
// window.location.href = marker.url;
// }
// }
function triggerClick(i) {
google.maps.event.trigger(markers[i], 'click');
//map.getBounds();
}
function triggerClick2(i) {
google.maps.event.trigger(markers2[i], 'click');
//map.getBounds();
}
function autoCenter() {
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds();
// Go through each...
for (var i = 0; i < markers.length; i++){
bounds.extend(markers[i].position);
}
// Fit these bounds to the map
map.fitBounds(bounds);
}
function autoCenter2() {
// Create a new viewpoint bound
var bounds2 = new google.maps.LatLngBounds();
// Go through each...
for (var i = 0; i < markers2.length; i++){
bounds2.extend(markers2[i].position);
}
// Fit these bounds to the map
map2.fitBounds(bounds2);
}
/* MAP FUNCTIONS */
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyApai5Yz8RBxzygQkoJXWoqehnZKeMJLQs&libraries=places&callback=initialize">
</script>
In the second loop you need change:
contentContainer.push('<div id="iw-container">'+locations2[i][3]+'</div>');
to
contentContainer2.push('<div id="iw-container">'+locations2[i][3]+'</div>');
in the same loop you need change:
markers.push(marker2);
to
markers2.push(marker2);
and you forgot add:
var infowindow2 = new google.maps.InfoWindow({
maxWidth: 350
});
The code updated:
<h1>Map 1</h1>
<div id="map-sao-paulo" class="mapa-home"></div>
<h1>Map 2</h1>
<div id="map-jundiai" class="mapa-home"></div>
<style>
.mapa-home {
width: 100%;
height: 600px;
background-color: grey;
}
</style>
<script>
var urlPortfolio = 'http://www.qd1.com.br/maptest/';
var urlTema = 'http://www.qd1.com.br/maptest/';
/* MAP FUNCTIONS */
var locations = [
['Rua Oscar Caravelas', -23.544130, -46.694866, 'Rua Oscar Caravelas', 'futuro', 'Rua Oscar Caravelas, Vila Madalena, São Paulo, SP','rua-oscar-caravelas'],
['Residencial Tangará Pinheiros', -23.561472, -46.681912, 'Residencial Tangará Pinheiros', 'entregue', 'Rua Cônego Eugenio Leite nº 866, Pinheiros, São Paulo, SP','residencial-tangara-pinheiros'],
['Home Studio 47', -23.553518, -46.678283, 'Home Studio 47', 'lancamento', 'R. Capote Valente, 980 - Pinheiros São Paulo - SP','home-studio-47'],
['Edifício Praça dos Pinheiros', -23.541635, -46.704697, 'Edifício Praça dos Pinheiros', 'entregue', 'Rua Antonio Borba, 489 Vila Madalena, São Paulo, SP','edificio-praca-dos-pinheiros'],
['Ed. Hit Paulista', -23.563348, -46.643135, 'Ed. Hit Paulista', 'lancamento', 'Rua Arthur Prado, 341, Bela Vista, São Paulo, SP','hit-paulista'],
['Ed. Praça de Veneza', -23.545856, -46.696868, 'Ed. Praça de Veneza', 'entregue', 'Av. das Corujas, 584 Alto de Pinheiros, São Paulo, SP','ed-praca-de-veneza'],
]
var locations2 = [
['Av. Américo Bruno', -23.189918, -46.869183, 'Av. Américo Bruno', 'futuro', 'Av. Américo Bruno, Jundiaí, SP','jundiai-av-americo-bruno'],
['Av. Frederico Ozanon', -23.183679, -46.877656, 'Av. Frederico Ozanon', 'futuro', 'Av. Frederico Ozanon, Jundiaí, SP','jundiai-av-frederico-ozanon'],
['Casas Vila Malota', -23.215822, -46.910892, 'Casas Vila Malota', 'entregue', 'Rua dos Jequitibás 850, Malota, Jundiaí, SP','casas-vila-malota'],
]
var markers = new Array();
var markers2 = new Array();
var map;
var map2;
var estilos = [
{
"featureType": "water",
"elementType": "geometry",
"stylers": [
{
"color": "#aaaaaa"
},
{
"lightness": 17
}
]
},
{
"featureType": "landscape",
"elementType": "geometry",
"stylers": [
{
"color": "#dddddd"
},
{
"lightness": 20
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#ffffff"
},
{
"lightness": 17
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#ffffff"
},
{
"lightness": 29
},
{
"weight": 0.2
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry",
"stylers": [
{
"color": "#ffffff"
},
{
"lightness": 18
}
]
},
{
"featureType": "road.local",
"elementType": "geometry",
"stylers": [
{
"color": "#ffffff"
},
{
"lightness": 16
}
]
},
{
"featureType": "poi",
"elementType": "geometry",
"stylers": [
{
"color": "#f5f5f5"
},
{
"lightness": 21
}
]
},
{
"featureType": "poi.park",
"elementType": "geometry",
"stylers": [
{
"color": "#a7ce84"
},
{
"lightness": 21
}
]
},
{
"elementType": "labels.text.stroke",
"stylers": [
{
"visibility": "on"
},
{
"color": "#ffffff"
},
{
"lightness": 16
}
]
},
{
"elementType": "labels.text.fill",
"stylers": [
{
"saturation": 36
},
{
"color": "#333333"
},
{
"lightness": 40
}
]
},
{
"elementType": "labels.icon",
"stylers": [
{
"visibility": "off"
}
]
},
{
"featureType": "transit",
"elementType": "geometry",
"stylers": [
{
"color": "#f1f1f1"
},
{
"lightness": 19
}
]
},
{
"featureType": "administrative",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#efefef"
},
{
"lightness": 20
}
]
},
{
"featureType": "administrative",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#efefef"
},
{
"lightness": 17
},
{
"weight": 1.2
}
]
}
];
var contentContainer = [];
var contentContainer2 = [];
function initialize() {
map = new google.maps.Map(document.getElementById('map-sao-paulo'), {
zoom: 14,
scrollwheel: false,
center: new google.maps.LatLng(-23.553518, -46.678283),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false,
panControl: false,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
},
styles: estilos
});
map2 = new google.maps.Map(document.getElementById('map-jundiai'), {
zoom: 14,
scrollwheel: false,
center: new google.maps.LatLng(-23.197818, -46.880150),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false,
panControl: false,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
},
styles: estilos
});
var infowindow = new google.maps.InfoWindow({
maxWidth: 350
});
var infowindow2 = new google.maps.InfoWindow({
maxWidth: 350
});
var iconCounter = 0;
var iconCounter2 = 0;
// Add the markers and infowindows to the map
for (var i = 0; i < locations.length; i++) {
contentContainer.push('<div id="iw-container">'+locations[i][3]+'</div>');
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
url: urlPortfolio + locations[i][6],
icon: urlTema + 'images/map-marker-'+locations[i][4]+'.png',
title: 'Saiba mais'
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function(){
infowindow.setContent('' + locations[i][3] + '');
infowindow.open(map, marker);
var lat = marker.getPosition().lat();
var lng = marker.getPosition().lng();
var latlng = new google.maps.LatLng(lat, lng);
map.setCenter(latlng);
}
})(marker, i));
}
for (var i = 0; i < locations2.length; i++) {
contentContainer2.push('<div id="iw-container">'+locations2[i][3]+'</div>');
var marker2 = new google.maps.Marker({
position: new google.maps.LatLng(locations2[i][1], locations2[i][2]),
map: map2,
url: urlPortfolio + locations2[i][6],
icon: urlTema + 'images/map-marker-'+locations2[i][4]+'.png',
title: 'Saiba mais'
});
markers2.push(marker2);
google.maps.event.addListener(marker2, 'click', (function (marker2, i) {
return function(){
infowindow2.setContent('' + locations2[i][3] + '');
infowindow2.open(map2, marker2);
var lat2 = marker2.getPosition().lat();
var lng2 = marker2.getPosition().lng();
var latlng2 = new google.maps.LatLng(lat2, lng2);
map2.setCenter(latlng2);
}
})(marker2, i));
}
google.maps.event.addListener(infowindow, 'domready', function() {
var iwOuter = jQuery('#map-sao-paulo .gm-style-iw');
iwOuter.css({'margin-top' : '0px','font-weight' : 'bold'});
var iwBackground = iwOuter.prev();
iwBackground.children(':nth-child(4)').css({'background-color': '#fff','border': 'solid 1px #aaa'});
iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'display: none;'});
iwBackground.children(':nth-child(2)').attr('style', function(i,s){ return s + 'display: none;'});
iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'display: none;'});
});
google.maps.event.addListener(infowindow2, 'domready', function() {
var iwOuter2 = jQuery('#map-jundiai .gm-style-iw');
iwOuter2.css({'margin-top' : '0px','font-weight' : 'bold'});
var iwBackground2 = iwOuter2.prev();
iwBackground2.children(':nth-child(4)').css({'background-color': '#fff','border': 'solid 1px #aaa'});
iwBackground2.children(':nth-child(1)').attr('style', function(i,s){ return s + 'display: none;'});
iwBackground2.children(':nth-child(2)').attr('style', function(i,s){ return s + 'display: none;'});
iwBackground2.children(':nth-child(3)').attr('style', function(i,s){ return s + 'display: none;'});
});
autoCenter();
autoCenter2();
}
// function loadURL(marker) {
// return function () {
// window.location.href = marker.url;
// }
// }
function triggerClick(i) {
google.maps.event.trigger(markers[i], 'click');
//map.getBounds();
}
function triggerClick2(i) {
google.maps.event.trigger(markers2[i], 'click');
//map.getBounds();
}
function autoCenter() {
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds();
// Go through each...
for (var i = 0; i < markers.length; i++){
bounds.extend(markers[i].position);
}
// Fit these bounds to the map
map.fitBounds(bounds);
}
function autoCenter2() {
// Create a new viewpoint bound
var bounds2 = new google.maps.LatLngBounds();
// Go through each...
for (var i = 0; i < markers2.length; i++){
bounds2.extend(markers2[i].position);
}
// Fit these bounds to the map
map2.fitBounds(bounds2);
}
/* MAP FUNCTIONS */
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?libraries=places&callback=initialize">
</script>
I'm developing a google map function to display GEOJson Data in a map.
According to the web, the following points are in montreal :
Point1 : lat = 45.555 and lng = -73.555
Point2 : lat = 45.666 and lng = -73.666
http://www.latlong.net/c/?lat=45.666&long=-73.666
So I've constructed my GEOJson data as follow (displaying two markers in Montreal):
var data_default = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [45.555, -73.555]
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [45.666, -73.666]
}
}
] };
However, for this data, the following function :
map.data.addGeoJson(data);
Is not indicated the points in Montreal .... to have Montreal I should inverse the latitude and lng of the "coordinates" .. so my two points should have the following coordinates : [-73.555, 45.555 ] [-73.666, 45.666] instead of [45.555, -73.555 ] [45.666,-73.666]
Is any one can explain to me why the addGeoJson of Google maps api is reading the points in an inverse way ?
Thank you
GeoJSON specifies coordinates as [longitude,latitude]. You have the coordinates backwards.
From the spec:
Point coordinates are in x, y order (easting, northing for projected coordinates, longitude, latitude for geographic coordinates):
code snippet:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(45.555, -73.555),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var data_default = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-73.555, 45.555]
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-73.666, 45.666]
}
}]
};
map.data.addGeoJson(data_default);
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>
I have the following code to detect the visitors GPS position and show it on the Google Maps JavaScript v3 map. Everything works as I want it but the code will not center or zoom as I want - it simple use the standard position (right over Asia)! I want it to fit the markers on the map.
var rendererOptions = {
draggable: false
};
if(navigator.geolocation) {
var timeoutVal = 10 * 1000 * 1000;
navigator.geolocation.watchPosition(
displayPosition,
displayError,
{ enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
);
} else {
alert('Din webbläsare stödjer inte någon geologisk lokalisering med hjälp av HTML5');
}
var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var directionsService = new google.maps.DirectionsService();
var marker_gps;
var map_gps;
var options_gps;
function displayPosition(position) {
/***********************
** GPS-POSITION **
************************/
directionsDisplay = new google.maps.DirectionsRenderer();
localStorage.coor = position.coords.latitude.toFixed(6) + ',' + position.coords.longitude.toFixed(6);
var gps_coor = new google.maps.LatLng(position.coords.latitude.toFixed(6), position.coords.longitude.toFixed(6));
if(typeof(marker) != 'undefined') marker.setMap(null);
localStorage.accuracy = position.coords.accuracy;
document.getElementById('accuracy').innerHTML = number_format(localStorage.accuracy) + ' meter';
directionsDisplay.setMap(map_gps);
directionsDisplay.setPanel(document.getElementById('directions-panel'));
marker_gps = new google.maps.Marker({
position: gps_coor,
draggable: false,
map: map_gps
});
var circle_gps = new google.maps.Circle({
center: gps_coor,
radius: position.coords.accuracy,
map: map_gps,
fillColor: '#3333ff',
fillOpacity: 0.2,
strokeColor: '#3333ff',
strokeOpacity: 0.5,
strokeWeight: 1
});
/*****************************
** FÄRDSÄTT (DISTANS) **
******************************/
var start = new google.maps.LatLng(position.coords.latitude.toFixed(6), position.coords.longitude.toFixed(6));
var stop = new google.maps.LatLng(<?php echo $photo['coordinates_latitude'].','.$photo['coordinates_longitude']; ?>);
var request = {
origin: start,
destination: stop,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if(status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
directionsService.route(request, function(response, status) {
if(status == google.maps.DirectionsStatus.OK) {
var distance = (response.routes[0].legs[0].distance.value / 1000).toFixed(0);
var duration = secondsToString(response.routes[0].legs[0].duration.value);
document.getElementById('distance').innerHTML = 'Cirka ' + distance + ' kilometer';
document.getElementById('duration').innerHTML = 'Cirka ' + duration;
directionsDisplay.setDirections(response);
}
});
}
function initialize_gps() {
var coor = new google.maps.LatLng(localStorage.coor);
var bounds = new google.maps.LatLngBounds();
options_gps = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: google.maps.LatLng(localStorage.coor),
streetViewControl: false
}
map_gps = new google.maps.Map(document.getElementById('map-distance'), options_gps);
map_gps.fitBounds(bounds);
}
function secondsToString(seconds) {
var numdays = Math.floor(seconds / 86400);
var numhours = Math.floor((seconds % 86400) / 3600);
var numminutes = Math.floor(((seconds % 86400) % 3600) / 60);
return (numdays != 0 ? (numdays == 1 ? '1 dag' : numdays + ' dagar') + ', ' : '')
+ (numhours != 0 ? (numhours == 1 ? '1 timme' : numhours + ' timmar') + (numdays != 0 ? ', ' : ' och ') : '')
+ (numminutes != 0 ? (numminutes == 1 ? '1 minut' : numminutes + ' minuter') : '');
}
function displayError(error) {
var errors = {
1: 'Permission denied',
2: 'Position unavailable',
3: 'Request timeout'
};
alert('Error: ' + errors[error.code]);
}
How can I make this to work?
Thanks in advance.
EDIT
Here's the edited part of the initialize_gps function. This part didn't work - nothing new happened. It just center the map over Asia like before.
function initialize_gps() {
var coor = new google.maps.LatLng(localStorage.coor);
var bounds = new google.maps.LatLngBounds();
options_gps = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: google.maps.LatLng(localStorage.coor),
streetViewControl: false
}
map_gps = new google.maps.Map(document.getElementById('map-distance'), options_gps);
map_gps.fitBounds(bounds);
}
EDIT
I have copy-pasted the whole code to jsFiddle. Link: http://jsfiddle.net/edgren/WRxt4/
The general solution to fitting the map display to a set of markers is to add them to an empty google.maps.LatLngBounds object (by calling bounds.extend), then calling map.fitBounds with that bounds.
function setMarkers(map) {
var bounds = new google.maps.LatLngBounds();
// Adds markers to the map.
for (let i = 0; i < beaches.length; i++) {
const beach = beaches[i];
var marker = new google.maps.Marker({
position: { lat: beach[1], lng: beach[2] },
map,
title: beach[0],
});
bounds.extend(marker.getPosition());
}
map.fitBounds(bounds);
}
// The following example creates complex markers to indicate beaches near
// Sydney, NSW, Australia. Note that the anchor is set to (0,32) to correspond
// to the base of the flagpole.
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 10,
center: { lat: 0, lng: 0 },
});
setMarkers(map);
}
// Data for the markers consisting of a name, a LatLng and a zIndex for the
// order in which these markers should display on top of each other.
const beaches = [
["Bondi Beach", -33.890542, 151.274856, 4],
["Coogee Beach", -33.923036, 151.259052, 5],
["Cronulla Beach", -34.028249, 151.157507, 3],
["Manly Beach", -33.80010128657071, 151.28747820854187, 2],
["Maroubra Beach", -33.950198, 151.259302, 1],
];
function setMarkers(map) {
var bounds = new google.maps.LatLngBounds();
// Adds markers to the map.
for (let i = 0; i < beaches.length; i++) {
const beach = beaches[i];
var marker = new google.maps.Marker({
position: { lat: beach[1], lng: beach[2] },
map,
title: beach[0],
});
bounds.extend(marker.getPosition());
}
map.fitBounds(bounds);
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Complex Marker Icons</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="map"></div>
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly"
async
></script>
</body>
</html>