Sencha Touch 2 App - functional requirement - javascript

Have developed an app in Sencha Touch V2.This app contains a Mappa panel where there is a map, this map has been populated with markers which corresponds to the various locations(cafes) that are taken from a json file.
The App Map panel functions as follows:
On a marker click the start and end locations textields pops ups, where the user enters the values for the start and end locations, another click to any of the other markers results in, the directions from start and end locations being plotted onto the map.
We need to implement the following functionality:
We need to facilitate the directions of locations entered in google maps plotted onto the map on a button click and also need to recreate the map instance(refresh map) and place existing markers on another button click(map clear button) so as to create a new instance for the user to find directions for different start and end locations.
Problems that we have are:
While defining the handler for the button click resulted in no action being performed(getting directions handler was not functioning).
Inorder to recreate the instance of the map, we had set the map to null but that resulted in a map without markers.
Could anyone please help out in accomplishing the tasks for this app in Sencha touch version 2.

Created this kind of application / functionality long time back.
You can create a floating formpanel and provide the field entries there for source and destination end points.
Then, you could write the below code on tap of "Get Directions" button,
Code snippet :-
tap: function() {
var src = Ext.getCmp('srcField');
var destn = Ext.getCmp('destField');
var mode = Ext.getCmp('travelMode');
var request = {
origin: src.getValue(),
destination: destn.getValue(),
travelMode: mode.getPressedButtons()[0].getText(),
};
Ext.Ajax.request({
url: 'http://maps.googleapis.com/maps/api/directions/json?origin='+src.getValue()+'&destination='+destn.getValue()+'&mode='+mode.getPressedButtons()[0].getText()+'&sensor=false';
method:'post',
success : function(response) {
showDirections(response,request);
}
});
function showDirections(res,req) {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var map = Ext.getCmp('googleMapComponentId').getMap();
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
directionsDisplay.setMap(map);
}
});
}

Related

how to change color to some streets on map [duplicate]

I am loading markers from a database and then drawing a polyline between markers. I am using the polyline to calculate overall distance instead of having to calculate the distance from marker-a to marker-b to marker-c and so on.
My distance is however inaccurate because if two markers are around a curved road, the polyline just connects them instead of drawing it along the road.
I know this is possible in Google Maps API but the usage restrictions would not suit me which is why I decided to use leaflet.
My markers are not so far apart, because my GPS device sends location every 10 seconds.
I found the leaflet-routing-machine plugin and I was wondering if I can use this to make my polyline snap to the road?
This is how I am adding markers to my map:
function getlocationsfromdb(){
group.clearLayers();
latlngArray.length=0;
var deviceid = $("#selectid").val();
$.ajax({
type: "POST",
url: "functionhandlers/getlocations.php",
data: {deviceid:deviceid,start:start,end:end},
dataType: 'json',
cache: false,
})
.success(function(response) {
$('input').removeClass('error').next('.errormessage').html('');
if(!response.errors && response.result) {
$.each(response.result, function( index, value) {
var latlng = L.latLng(value[7], value[8]);
var marker = L.circleMarker(latlng,{radius:2}).addTo(group);
latlngArray.push(latlng);
});
var polyline = L.polyline(latlngArray, {color: '#605ca8'}).addTo(group);
map.fitBounds(group.getBounds());
var distancetravelled=polyline.measuredDistance();
$("#distancetravelled").html(distancetravelled);
} else {
$.each(response.errors, function( index, value) {
// add error classes
$('input[name*='+index+']').addClass('error').after('<div class="errormessage">'+value+'</div>')
});
}
});
}
Can someone please point me in the right direction?
This can be done rather easily with leaflet-routing-machine. You can just set the waypoints to your latlngArray when you initialize the routing control:
var control = L.Routing.control({
waypoints: latlngArray,
show: false,
waypointMode: 'snap',
createMarker: function() {}
}).addTo(map);
Here, show: false keeps the control from displaying on the map, and the empty createMarker function overrides the default markers that routing machine creates, instead doing nothing (though the markers would be removed when we remove the control, this just keeps them from flashing on the screen when a route is found).
You can extract all the vertices of the routing machine results by listening for the routeselected event, which will return an IRoute object that contains all the directions and geometries for the route. Placing the .route.coordinates in a new L.polyline object will keep the route around, so we can then just get rid of the routing control:
control.on('routeselected', function(e) {
L.polyline(e.route.coordinates).addTo(group);
map.removeControl(control);
});
Placing the above code blocks within your .success callback function right after you populates your latlngArray should give you the route you want. Here's a fiddle showing this at work:
http://fiddle.jshell.net/nathansnider/ygktexbj/
Also, if you're not using the routing control for anything else and want to keep it from showing up entirely (a small white control box may still appear while the route is being calculated), you can simply hide it in CSS:
.leaflet-routing-container {
display:none;
}
I realize that this solution is a bit roundabout, since it creates a control, and then half the code is just preventing that control from showing up on the map
You actually don't have to add it to the map. Furthermore you can attack inner router's route function directly.
var routingControl = L.Routing.control({
waypointMode: 'snap'
});
then
routingControl._router.route(latLngCoordinates, function(err, waypoints) {
var a = waypoints;
});
Be careful, it's raw copy/paste:
- waypoints fits internal format (inspect it)
- latLngCoordinates must be in {lat:, lng:} format
- it might require some cleaning because the url generated encapsulate some very long "hints" data.

Uncaught ReferenceError: infowindow is not defined #googleMaps API

I'm trying to integrate the Google maps API to my page. I use a code that extract the locations from JSON and saves the location in an array, then return the place-data of each location. Everything went well except I can't activate the infowindow function when clicking on marker on the map. This is the error that appears when clicking:
var map; // declares a global map variable
/*
Start here! initializeMap() is called when page is loaded.
*/
function initializeMap() {
var locations;
var mapOptions = {
disableDefaultUI: true
};
/*
For the map to be displayed, the googleMap var must be
appended to #mapDiv in resumeBuilder.js.
*/
map = new google.maps.Map(document.querySelector('#map'), mapOptions);
/*
locationFinder() returns an array of every location string from the JSONs
written for bio, education, and work.
*/
function locationFinder() {
// initializes an empty array
var locations = [];
// adds the single location property from bio to the locations array
locations.push(bio.contacts.location);
// iterates through school locations and appends each location to
// the locations array. Note that forEach is used for array iteration
// as described in the Udacity FEND Style Guide:
// https://udacity.github.io/frontend-nanodegree-styleguide/javascript.html#for-in-loop
education.schools.forEach(function(school){
locations.push(school.location);
});
// iterates through work locations and appends each location to
// the locations array. Note that forEach is used for array iteration
// as described in the Udacity FEND Style Guide:
// https://udacity.github.io/frontend-nanodegree-styleguide/javascript.html#for-in-loop
work.jobs.forEach(function(job){
locations.push(job.location);
});
return locations;
}
/*
createMapMarker(placeData) reads Google Places search results to create map pins.
placeData is the object returned from search results containing information
about a single location.
*/
function createMapMarker(placeData) {
// The next lines save location data from the search result object to local variables
var lat = placeData.geometry.location.lat(); // latitude from the place service
var lng = placeData.geometry.location.lng(); // longitude from the place service
var name = placeData.formatted_address; // name of the place from the place service
var bounds = window.mapBounds; // current boundaries of the map window
// infoWindows are the little helper windows that open when you click
// or hover over a pin on a map. They usually contain more information
// about a location.
var infoWindow = new google.maps.InfoWindow({
content: name
});
// marker is an object with additional data about the pin for a single location
var marker = new google.maps.Marker({
map: map,
position: placeData.geometry.location,
title: name
});
// hmmmm, I wonder what this is about...
marker.addListener('click', function() {
// your code goes here!
infowindow.open(map, marker);
});
// this is where the pin actually gets added to the map.
// bounds.extend() takes in a map location object
bounds.extend(new google.maps.LatLng(lat, lng));
// fit the map to the new marker
map.fitBounds(bounds);
// center the map
map.setCenter(bounds.getCenter());
}
/*
callback(results, status) makes sure the search returned results for a location.
If so, it creates a new map marker for that location.
*/
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
createMapMarker(results[0]);
}
}
/*
pinPoster(locations) takes in the array of locations created by locationFinder()
and fires off Google place searches for each location
*/
function pinPoster(locations) {
// creates a Google place search service object. PlacesService does the work of
// actually searching for location data.
var service = new google.maps.places.PlacesService(map);
// Iterates through the array of locations, creates a search object for each location
locations.forEach(function(place){
// the search request object
var request = {
query: place
};
// Actually searches the Google Maps API for location data and runs the callback
// function with the search results after each search.
service.textSearch(request, callback);
});
}
// Sets the boundaries of the map based on pin locations
window.mapBounds = new google.maps.LatLngBounds();
// locations is an array of location strings returned from locationFinder()
locations = locationFinder();
// pinPoster(locations) creates pins on the map for each location in
// the locations array
pinPoster(locations);
}
/*
Uncomment the code below when you're ready to implement a Google Map!
*/
// Calls the initializeMap() function when the page loads
window.addEventListener('load', initializeMap);
// Vanilla JS way to listen for resizing of the window
// and adjust map bounds
window.addEventListener('resize', function(e) {
// Make sure the map bounds get updated on page resize
map.fitBounds(mapBounds);
});
You are trying to create an infoWindow object here:
// infoWindows are the little helper windows that open when you click
// or hover over a pin on a map. They usually contain more information
// about a location.
var infoWindow = new google.maps.InfoWindow({
content: name
});
and then work with it (show message after marker click)
// hmmmm, I wonder what this is about...
marker.addListener('click', function() {
// your code goes here!
infowindow.open(map, marker);
});
But look at your variables attentively:
infoWindow !== infowindow (letter W)
browser doesn't know, what infowindow is, and falls with an error.
Read more about variables naming in JS here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Declarations
I came across this question while trying to debug some code that I had copied from the Udacity tutorial (Getting Started with the APIs) that Hasam was drawing from. My code, as copied from the video itself, lacked some key lines, and wouldn't run correctly. The tutorial's 'resources' didn't have a copy of the code. I eventually found a good copy of the code on Github: https://github.com/udacity/ud864. As I wrote this answer, I found the same link tucked away on the bottom of some of the Udacity tutorial pages themselves.

Recenter Google map after map canvas changes size API

I am using the Google Maps API v.3 to create a google map with directions very similar to this example by google.
The main difference is that on page load, the google map canvas is set to 100%, and when the user requests directions the map is reduced to 70% (to make room for the directions panel)
When the user gets directions, the directions are displayed as if the map canvas was at 100%, not 70%, essentially cutting off part of the directions. I need the map to reorient / recenter when the direction response is displayed.
You can demo this out here: http://j2designpartnership.com/directions/
When the user types in directions, this function is called: calcRoute()
function calcRoute() {
if (document.getElementById("start").value != "") {
activeSettings();
}
else{
defaultSettings();
}
var start = document.getElementById("start").value;
var end = document.getElementById("end").value;
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
//make the request for our directions
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
var recenter = new google.maps.LatLng(40.440625,-79.995886);
map.setCenter(recenter);
}
The part to pay attention to here is the top conditional that basically changes the width of the map canvas if there is text in the input field.
How do I recenter the map now that the map canvas is smaller?
When the map div changes size trigger the resize event on the map as specified in the documentation
resize | None | Developers should trigger this event on the map when the div changes size:
google.maps.event.trigger(map, 'resize') .

Custom control to get coordinates from a point in Google API

I'm using JavaScript Google API to build a map for my site (that is going to work for tablets, not for PCs)
I am getting all the markers from the .NET doc;
I want to make a new custom control, and when a user will choose it he will able to click on some point on the map and get the coordinates to a text field.
So I know how to make a new control, and I know how to click on some point in the map and get the coordinates:
When I click I get the lat and long:
google.maps.event.addListener(map, "rightclick", function(event) {
var latFromMap = event.latLng.lat();
var lngFromMap = event.latLng.lng();
// populate yor box/field with lat, lng
document.getElementById("lat").value = latFromMap;
document.getElementById("long").value = lngFromMap;
});
And to make a control (that will take us back to center):
google.maps.event.addDomListener(outer, 'click', function() {
map.setCenter(getcenter)
});
Now. I want to connect them. So only when I click on the control I will be able to check the lat/long in some point.
You may create a new styledMapType as described here (you don't need the styling, simply create the mapType and add it to the controls).
When you do so you have 2 results at once, that you need for your project:
The control, and a property that you can check everytime to determine if the control is active, the mapTypeId
Applying the click would be easy then:
google.maps.event.addListener(map, 'click', function() {
if(this.mapTypeId=='mapTypeIdOfTheStyledMap'){
//execute click-action
}
});
Demo: http://jsfiddle.net/doktormolle/kbXGd/

Opening a second InfoWindow in Google Maps API v3

I'm implementing a Maps interface for a database of music venues and events and have run into an interesting issue. I have a series of HTML elements with onclick calls to a certain Javascript function. The calls run correctly and the javascript function runs correctly the first time (all the information is passed in correctly and my debug alerts display it correctly), and the infoWindow displays. The second time I click on one of these divs, the first one closes correctly, the final alert in the code below fires with the correct information, but the new InfoWindow does not pop up.
Map setup code:
function mapsInitialize() {
var mapOptions = {
center: new google.maps.LatLng(42.4439614, -76.5018807),
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("mapSection"), mapOptions);
google.maps.event.trigger(map, 'resize');
for(var x = 0; x < markers.length; x++){
var tempOptions = {
position: markers[x].position,
title: markers[x].name,
map: map
}
markerObjects[markers[x].title] = new google.maps.Marker(tempOptions);
}
}
Function called onclick from the divs:
function generateInfoWindow(despacedName, despacedTitle, eventTitle, url, date, time){
if(curInfoWindow){
alert("closing " + curInfoWindow.getContent());
curInfoWindow.close();
curInfoWindow = null;
}
curInfoWindow = new google.maps.InfoWindow(options = {size: new google.maps.Size(150,50)});
curInfoWindow.setContent("<a class=\"eventLink\" href=\""+url+"\">"+eventTitle+"</a><br><br>"+markerObjects[despacedName].title+"<br>"+date+" at "+time);
curInfoWindow.open(map, markerObjects[despacedName]);
alert(despacedName+" is "+markerObjects[despacedName]);
}
I can guarantee that the markers[] array is fed correctly.
I have tried, among other things...
Creating an array to hold the infoWindows instead of using one curInfoWindow variable
Not having anything in the array automatically close like the beginning of the generateInfoWindow() function does
Creating the info windows automatically in the mapsInitialize() function
Most of the results on Google when searching for solutions brought me information about event listeners on the map - is that the only way to fire an event like this, or is what I'm trying to do valid?
If any other code examples are needed, let me know. Thanks for any suggestions!
According to Google Maps API:
InfoWindows may be attached to either Marker objects (in which case
their position is based on the marker's location) or on the map itself
at a specified LatLng. If you only want one info window to display at
a time (as is the behavior on Google Maps), you need only create one
info window, which you can reassign to different locations or markers
upon map events (such as user clicks). Unlike behavior in V2 of the
Google Maps API, however, a map may now display multiple InfoWindow
objects if you so choose.
Maybe this would work:
function generateInfoWindow(despacedName, despacedTitle, eventTitle, url, date, time){
if(!curInfoWindow){
curInfoWindow = new google.maps.InfoWindow({maxWidth:150});
}
curInfoWindow.setContent("<a class=\"eventLink\" href=\""+url+"\">"+eventTitle+"</a><br><br>"+markerObjects[despacedName].title+"<br>"+date+" at "+time);
curInfoWindow.open(map, markerObjects[despacedName]);
alert(despacedName+" is "+markerObjects[despacedName]);
}
According to the specs, this should move the existing curInfoWindow to a new marker and update the content.
Note: this code is invalid
new google.maps.InfoWindow(options = {size: new google.maps.Size(150,50)})
There is no size attribute. The best you can do is
new google.maps.InfoWindow({maxWidth:150})
More about InfoWindow API

Categories

Resources