3 years 1 month ago - 3 years 1 month ago #110337 by BCorfman
Hello,

I'm trying to implement a survey where someone picks a location on one map, and then picks a location on another map, and it calculates the distance between those two points.

To do this I'm attempting to implement a modified version of tpartner's code from this page: www.limesurvey.org/en/community-services...on?start=10&start=20

But no matter what I try, I can't get this to work. I have absolutely no experience with Javascript so I've been trying to stumble my way through it, but can't figure it out. Here is the code I modified and attached to question 2:
```<script type="text/javascript" charset="utf-8">

// Identify the map
var map2SGQA = '{SGQ}';
var map1SGQA = '774328X12X32';
var currentMap = gmaps[''+map2SGQA+'_c'];

// Wait for the map to load

// Some variable definitions
var currentMarker = gmaps['marker__'+map2SGQA+'_c'];
var startLat = \$('{INSERTANS:'+map1SGQA+'}').val().split(';')[0];
var startLng = \$('{INSERTANS:'+map1SGQA+'}').val().split(';')[1];
var startLatLng = new google.maps.LatLng(startLat, startLng);

// Listener on the map events
calculateDistances(startLatLng, currentMarker.getPosition());
});
calculateDistances(startLatLng, currentMarker.getPosition());
});
calculateDistances(startLatLng, currentMarker.getPosition());
});

// Insert the results element

});
});

function calculateDistances(origin, destination) {
service.getDistanceMatrix({
origins: [origin],
destinations: [destination],
avoidHighways: false,
avoidTolls: false
}, callback);
}

function callback(response, status) {
} else {

var outputDiv = \$('.questiontext');
outputDiv.innerHTML = '';

for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
Distance: '+results[j].distance.text+'<br />\
Time: '+results[j].duration.text+'');
}
}
}
}
</script>```

I could also see doing this by setting the start point of the second map to the answer of the first map, but because of how map questions output answers I can't figure out how to get that to work either.

Edit:

When putting both maps on the same page and using the following code, I have gotten this to work somewhat. Unfortunately it won't change the starting location after it has tried calculating everything once, so if anyone has any suggestions there I'd like to fix that.
```<script type="text/javascript" charset="utf-8">

// Identify the map
var map2SGQA = '{SGQ}';
var map1SGQA = '774328X12X32';
var currentMap = gmaps[''+map2SGQA+'_c'];
var prevMap = gmaps[''+map1SGQA+'_c'];

// Wait for the map to load

// Some variable definitions
var currentMarker = gmaps['marker__'+map2SGQA+'_c'];
var prevMarker = gmaps['marker__'+map1SGQA+'_c'];
var startLatLng = new google.maps.LatLng(startLat, startLng);

// Listener on the map events
startLatLng = prevMarker.getPosition();
});
startLatLng = prevMarker.getPosition();
});
startLatLng = prevMarker.getPosition();
});

calculateDistances(startLatLng, currentMarker.getPosition());
});
calculateDistances(startLatLng, currentMarker.getPosition());
});
calculateDistances(startLatLng, currentMarker.getPosition());
});

// Insert the results element

});
});

function calculateDistances(origin, destination) {
service.getDistanceMatrix({
origins: [origin],
destinations: [destination],
avoidHighways: false,
avoidTolls: false
}, callback);
}

function callback(response, status) {
} else {

var outputDiv = \$('.questiontext');
outputDiv.innerHTML = '';

for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
Distance: '+results[j].distance.text+'<br />\
Time: '+results[j].duration.text+'');
}
}
}
}
</script>```
Last Edit: 3 years 1 month ago by BCorfman.

3 years 1 month ago - 3 years 1 month ago #110377 by tpartner
I would use something like the script below. This puts listeners on two maps on a page and when they are moved, calculates the addresses and distance and loads it into a long-text type question.

```<script type="text/javascript" charset="utf-8">

// Identify the elements
var map1Question = \$('input.text.location:eq(0)').closest('.text-short');
var map2Question = \$('input.text.location:eq(1)').closest('.text-short');
var map1SGQA = \$('input.text.location', map1Question).attr('id').replace(/answer/, '').replace(/_c/, '');
var map1 = gmaps[''+map1SGQA+'_c'];
var marker1 = gmaps['marker__'+map1SGQA+'_c'];
var map2SGQA = \$('input.text.location', map2Question).attr('id').replace(/answer/, '').replace(/_c/, '');
var map2 = gmaps[''+map2SGQA+'_c'];
var marker2 = gmaps['marker__'+map2SGQA+'_c'];
var resultsInput = \$('.text-long:eq(0) .textarea');

// Disable the results textarea

// Wait for the maps to load
// Listeners on the map 1 events
updateDistance();
});
updateDistance();
});
updateDistance();
});
});
// Listeners on the map 2 events
updateDistance();
});
updateDistance();
});
updateDistance();
});
});

function updateDistance() {
var startLat = \$(map1Input).val().split(' ')[0];
var startLng = \$(map1Input).val().split(' ')[1];
var startLatLng = new google.maps.LatLng(startLat, startLng);
var endLat = \$(map2Input).val().split(' ')[0];
var endLng = \$(map2Input).val().split(' ')[1];
var endLatLng = new google.maps.LatLng(endLat, endLng);

calculateDistances(startLatLng, endLatLng);
}

function calculateDistances(origin, destination) {
service.getDistanceMatrix({
origins: [origin],
destinations: [destination],
avoidHighways: false,
avoidTolls: false
}, callback);
}

function callback(response, status) {
} else {

for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
}
}
}
}

});
</script>```

Here's a working 2.05 survey with the script in the source of the first map question.

#### File Attachment:

File Name: limesurvey...6-25.lss
File Size:22 KB

.

Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
##### Attachments:
Last Edit: 3 years 1 month ago by tpartner.
The following user(s) said Thank You: dglp

3 years 1 month ago - 3 years 1 month ago #110563 by BCorfman
Thanks so much, this works pretty much perfectly.

Edit: The problems below are suddenly not happening anymore; go figure. I would like to know if there's a reason why the following listener inserted into the code you provided doesn't react to the map center changing when the geocoder changes the map center:

listener:
```google.maps.event.addListener(map1, 'center_changed', function() {
updateDistance();
});```

Geocoding (there is a second one of these attached to the second map with all the 1s replaced with 2s):
```<script>
var geocoder1;
var mapgeo1;
var markergeo1;
function initialize1() {
mapgeo1 = gmaps[''+'{SGQ}_c'];
markergeo1 = gmaps['marker__{SGQ}_c'];
}
var coords1 = String(results1[0].geometry.location)
coords1 = coords1.replace(/\(?\)?\,?/g, '')
mapgeo1.setCenter(results1[0].geometry.location);
markergeo1.setPosition(results1[0].geometry.location);
} else {
alert('Geocode was not successful for the following reason: ' + status1);
}
});
}

</script>```

button (again, another one on the second map):
```<div id="panel">

I am trying to get it to work with a geocoder, and both sets of js work fine individually, but for some reason whenever I try searching with the search box element that calls the geocoder it makes the distance calculation js stop working. Here's the code for the geocoding:

-removed-

And then, of course, I added lines like this into the distance js (though they have nothing to do with it not working)

-removed-

Any idea why these aren't interacting well? I tried to make them not have any overlapping variables or anything in case that was the problem but it hasn't helped.

Edit: Oh, and here's the button in case it matters:
-removed-
Last Edit: 3 years 1 month ago by BCorfman.

3 years 1 month ago #110619 by tpartner
Can you attach a test survey with your code?

Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.