google maps v2 to v3: roadmap getTile() why doesn't work? - google-maps-api-3

Why this v2-like construction doesn't work in v3?
(instead roadmap tile path I get undefined)
var mytype = new google.maps.ImageMapType({
getTileUrl: function(tile, zoom) {
var url = '';
if (cond_need_custom_tiles) {
url = 'http://domain.com/mytiles/tile-'+tile.x+'-'+tile.y+'-'+zoom;
}
else { // need ROADMAP tiles
// old (v2):
// url = G_NORMAL_MAP.getTileLayers()[0].getTileUrl(tile, zoom);
// new (v3):
url = map.mapTypes.get(google.maps.MapTypeId.ROADMAP).getTile(tile, zoom); // why it doesn't work??
}
console.log(url); // undefined!!! why?
return url;
},
tileSize: new google.maps.Size(256, 256),
minZoom: 0,
maxZoom: Number(opt.zoom),
name: 'mytiles',
});
PS: I want my tiles mapType and ROADMAP in background (where no my tiles), thanks.

getTile() is no longer defined for basemaps; it should be used only as a user defined method on custom mapTypes -- please see comment #2 of http://code.google.com/p/gmaps-api-issues/issues/detail?id=3635#c2 for some additional details.
In your particular use case, perhaps you can simply always load the ROADMAP tiles by default, and then display your custom imageMapType as appropriate depending on cond_need_custom_tiles ?
Alternatively the bug noted above would be a good place to provide additional details on your use case.

Related

Add video in aframe dynamically

My requirement is to simply play a video (url in json file) on a plane in aframe. I have created video entity in my html as follows
<a-video id="video_1" position="0 0 2" geometry="width:2.4;height:1.4"></a-video>
Inside my register component i have added the src file to video as below
AFRAME.registerComponent('myComp', {
schema: {
file: {type: 'asset', default: 'assets/data/file1.json'},
var: {type: 'number', default: 0}
},
init: function () {
},
update: function () {
var data = this.data;
var scene = this.el.sceneEl;
var screen = scene.querySelector('#video_' + data.var);
load(data.file, function (response) {
var products = response.mydata;
screen.setAttribute('src',products[data.var].videoUrl);
});
this.el.addEventListener('mouseenter', function () {
console.log("mouseenter",screen.getAttribute('src'));
});
}
});
My console log is displayed with path mentioned in the json file
"mouseenter assets/img/movies/videos/video1.mp4"
In network tab, i could see my file got fetched with type media and status 200. But still i am getting error
components:texture:warn `$s` is not a valid video +41ms assets/img/movies/videos/video1.mp4
index.html:1 [.Offscreen-For-WebGL-000000BA313F15D0]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
What is the correct way to add the video. Where am i going wrong. Please help
I was having the same problem and just managed to get it work in Chrome with something like this:
// Create a new asset
var new_asset = document.createElement('video');
new_asset.setAttribute('id', 'dynVid'); // Create a unique id for asset
new_asset.setAttribute('src', videoUrl);
// Append the new video to the a-assets, where a-assets id="assets-id"
document.getElementById('assets-id').appendChild(new_asset);
// Add the asset to the a-video
screen.setAttribute('src', '#dynVid');
// Start playback
new_asset.play();
This has the added benefit that you can control playback if necessary (new_asset.pause(), new_asset.currentTime = X, muted = true, etc).
For larger videos, you may need to add some callbacks, like oncanplaythrough, to wait until the video has loaded enough.
https://aframe.io/docs/0.5.0/guides/using-javascript-and-dom-apis.html#creating-an-entity-with-createelement
var videoEl = document.createElement('a-video');
videoEl.setAttribute('src', videoUrl);
this.el.appendChild(videoEl);

fire click event on individual marker while using leaflet markercluster plugin

My site consists of a Leaflet map with the leaflet.markerclusters plugin. I am also using Flowplayer to play a video that opens in a JQuery Tools overlay using the selector id "#video1".
Currently, when I click on any marker on the map it fires my test video in an overlay. My goal is to create a click event unique to each individual marker in the cluster. Eventually, I would like every marker to have a click event that fires a video unique to that marker.
I am a beginner, and have been doing okay using these well documented libraries up until now. However, I don't have the skills to bridge this current gap. Would someone please give me a push in the right direction? Below is a link to my JS Fiddle. My issue begins on JavaScript line 2098.
var markers = new L.MarkerClusterGroup();
var addressPoints = [
[40.634902, -73.965054, "Video1"],
[40.660897, -73.961082, "Video2"],
[40.693353, -73.970413, "Video3"],
[40.693289, -73.966289, "Video4"],
[40.68973, -73.971007, "Video5"],
[40.718423, -73.957428, "Video6"],
[40.71817, -73.956918, "Video7"],
[40.681427, -73.993959, "Video8"]
];
for (var i = 0; i < addressPoints.length; i++) {
var a = addressPoints[i];
var title = a[2];
var marker = new L.Marker(new L.LatLng(a[0], a[1]), {
title: title
});
marker.bindPopup(title);
markers.addLayer(marker);
}
map.addLayer(markers);
//assign video div ID to overlay
$('#video1').overlay({
load: false,
top: "center",
left: "center"
});
//bind marker click event to overylay
markers.on('click', function () {
$("#video1").data("overlay").load();
});
Thank you,
Joey
http://jsfiddle.net/Joey84/nM458/26/
You are headed in the right direction with the markers.on("click"... function. You just need to make a few edits. Just as you added the event listener to the entire "markers" layer, you can add it to individual markers in your for loop.
...
for (var i = 0; i < addressPoints.length; i++) {
var a = addressPoints[i];
var title = a[2];
var marker = new L.Marker(new L.LatLng(a[0], a[1]), {
title: title
});
if (title=="Video1") {
marker.on('click', function () {
$("#video1").data("overlay").load();
});
}
marker.bindPopup(title);
markers.addLayer(marker);
}
...
Likewise - and probably the better solution - you can access details about the marker you clicked in the on("click"... you are currently using by passing a variable to the function. This would be useful if you have multiple videos and don't want to check with an if statement when creating markers.
markers.on('click', function (d) {
// Grab marker title and make it look like an ID
var marker_title = "#" + d.layer.options.title.toLowerCase();
// Make sure the jQuery object exists
if ( $(marker_title) ){
// Call up the video.
$(marker_title).data("overlay").load();
}
});
Note that I used toLowerCase() because your data has the title capitalized and the video id is all lowercase.
Here it is in action:
http://jsfiddle.net/nM458/44/

Google Maps and Location

I'm building an application using CakePHP that will store events including the event location. When a user visits the application they will see a Google Map that will get their location and show events near them in the form of little pins that they can click on to view the event details.
I have some questions though:
1.) How would I store the Location in the DB? Would the actual geolocation coordinates be the best bet and how would I make it easy for a user to create an event and enter them.
2.) Once I have the events in place how do I create custom pins with the info pulled from the DB? Example like foursquare:
3.) Whilst getting the users location using HTML5 Geolocation how do I show a little loader on the map again like Foursquare does?
So far I've managed to create the Map and make the controls minified and get the location of the viewer but I'm not sure how do 3 and show a better feedback to the user for the geolocation.
If someone could help me with those other two questions as well it'd be very much appreciated as I'm finding it very confusing so far. Thanks.
var map;
function initialize() {
var myOptions = {
zoom: 8,
panControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
overviewMapControl: false,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
myOptions);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
var infowindow = new google.maps.InfoWindow({
map: map,
position: pos,
content: 'Location found using HTML5.'
});
map.setCenter(pos);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var infowindow = new google.maps.InfoWindow(options);
map.setCenter(options.position);
}
google.maps.event.addDomListener(window, 'load', initialize);
1) Store the actual coordinates of the location and any extra meta data (if you have it) like place name, foursquare_id, date, etc. Storing it this way will make using the data later on straightforward, such as plotting on a map or location name lookup. This will be your Location model.
Create an Event model which you can then associate to a Location. You could hack together some nice interactive functionality using event handlers on your map markers.
Something like: "the user clicks a location on the map, up pops a box asking them would like like to create a new event at this location, marker is added to the map and a form appears where they can populate the event details, etc, etc." You get the idea.
Have a look at the Marker documentation.
2) You can set a custom image for the map markers using ImageMarker Class. Take a look at the huge set of examples for ideas of what's possible.
3) The navigator.geolocation.getCurrentPosition() method as I understand it, is asynchronous. The first argument is the successCallback.
With this in mind, you could set an overlay on your map: "Finding your location", then make the call to getCurrentPosition(). In your successCallback function, you would then hide the overlay.

jQuery Mobile + jQuery UI google maps + Fusion Markers

this has been baking my noodle for months, I'll be honest, I am a designer not a programmer so this type of scripting is a bit harder than the average jquery/javascript that I'm used too.
I can't find any basic documentation on how to implement it, apart from this but it's not massively intuitive - http://jquery-ui-map.googlecode.com/svn/trunk/demos/jquery-mobile-example.html
I've tried making a JSfiddle, but I can't even get it to work (now working thanks to Tsar)
I've built a jQuery mobile app and I'm desperate to get the geo-location functionality working with fusion table markers (from my fusion table) and to be allowed to click on the fusion table markers to reveal a info window. This info window will be constructed in fusion tables.
I need the geo-location to center the map on the devices current location - if the geo-location is not available or denied by device user, then the map needs to be centered on these co-ordinates 52.450939, -1.721002.
What would be the next level is to have the the jQuery mobile UI pop-up window but this is not critical, just the standard bubble on the map is fine.
A updated JSFiddle... http://jsfiddle.net/twGHC/30/
My fusion table number is: 1260763
Default location is: (only if Geo location is not available) 52.450939, -1.721002
Zoom level: 13
Any advice would be awesome, please feel free to JSfiddle it. Thanks in advance.
Here's a working solution, which detects user's location, drops a marker on it and plots the map with your Fusion Markers. As per Google Maps v3 API documentation:
$(function() {
var position = new google.maps.LatLng(52.450939, -1.721002);
getCurrentPosition = function(callback) {
// Try W3C Geolocation (Preferred)
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(pos) {
position = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
callback(position);
}, callback(position));
} // Try Google Gears Geolocation
else if (google.gears) {
var geo = google.gears.factory.create('beta.geolocation');
geo.getCurrentPosition(
function(pos) {
position = new google.maps.LatLng(pos.latitude,pos.longitude);
callback(position);
}, callback(position));
} // Browser doesn't support Geolocation
else {
// Drop the user off in Coventry =)
callback(position);
}
};
// call the above function
getCurrentPosition(InitMap);
});
function InitMap(pos) {
map = new google.maps.Map(document.getElementById('map_canvas'), {
center: pos,
zoom: 14,
mapTypeId: 'roadmap'
});
var marker = new google.maps.Marker({
position: pos,
animation: google.maps.Animation.DROP,
map: map,
title: "You are here, mate!"
});
var layer = new google.maps.FusionTablesLayer({
query: {
select: 'Geocodable address',
from: '1260763'
},
});
layer.setMap(map);
};
When user denies tracking of his location, exception is caught in getCurrentPosition, however, 2nd optional parameter in this function is an exception handler, so what I did is simply passed in callback(position) so that default location sets on the map. If you don't want to do it, move out the map initializer code from InitMap into separate function and call it instead, when exceptions are caught, to display a blank map.
See it in action here: http://jsfiddle.net/twGHC/36/
P.S. In case your next question is "how to add a balloon pop-up on marker click", here's what you need to do.
Here is how to do it with jquery-ui-map:
http://jsfiddle.net/rweCf/1/
http://jsfiddle.net/rweCf/1/embedded/result/
If you just want to change within a certain radius of the client position this is how you would do it
http://jsfiddle.net/Ywknf/1/ (client location is the initial point so everyone can see the results)
Here is the code if the url isnt working or the trunk code changed
$(function() {
$('#map_canvas').gmap({'center': '52.450939, -1.721002', 'zoom': 10, 'disableDefaultUI': true, 'mapTypeId': 'terrain'}).bind('init', function(event, map) {
$('#map_canvas').gmap('getCurrentPosition', function(results, status) {
if ( status === 'OK' ) {
var position = new google.maps.LatLng(results.coords.latitude, results.coords.longitude);
var marker = $('#map_canvas').gmap('get', 'markers > client' );
if ( !marker ) {
$('#map_canvas').gmap('addMarker', { 'id': 'client', 'position': position, 'bounds': true });
} else {
marker.setPosition(position);
map.panTo(position);
}
} else if ( status === 'NOT_SUPPORTED' ) {
$('#map_canvas').gmap('addMarker', { 'id': 'client', 'position': $('#map_canvas').gmap('get', 'map').getCenter(), 'bounds': true });
}
});
$('#map_canvas').gmap('loadFusion', { 'query': { 'select': 'Geocodable address', 'from': 1260763 } } );
});
});

Draggable Marker to Update Lat and Long Fields

I wonder whether someone may be able to help me please.
I've put some coding together (please see below) whereby a user goes onto a HTML form, they type in an address and click a 'Search' button. Upon doing this, the location is plotted on the Google map and the Lat and Long co-oridnates are automatically entered into the associated text boxes on my form.
What I would like to do, if at all possible, is for the marker to be draggable so the user can fine tune the location, and as they drag the marker, I'd like for the Lat and Long fields to change their
associated co-ordinates.
In addition, I'd also like, if at all possible, to have a field on the form called 'NearestAddress' to show the nearest address to where the marker has been dragged to.
I've managed to make the markers draggable but they don't update the Latitude and Longitude text boxes. I'm also unsure how to add the functionality to show the updated address to where the marker has been dragged to.
(function() {
// Defining some global variables
var map, geocoder, myMarker, infowindow;
window.onload = function() {
// Creating a new map
var options = {
zoom: 3,
center: new google.maps.LatLng(55.378051,-3.435973),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), options);
// Getting a reference to the HTML form
var form = document.getElementById('LocationSearchForm');
// Catching the forms submit event
form.onsubmit = function() {
// Getting the address from the text input
var address = document.getElementById('Address').value;
// Making the Geocoder call
getCoordinates(address);
// Preventing the form from doing a page submit
return false;
}
}
// Create a function the will return the coordinates for the address
function getCoordinates(address) {
// Check to see if we already have a geocoded object. If not we create one
if(!geocoder) {
geocoder = new google.maps.Geocoder();
}
// Creating a GeocoderRequest object
var geocoderRequest = {
address: address
}
// Making the Geocode request
geocoder.geocode(geocoderRequest, function(results, status) {
// Check if status is OK before proceeding
if (status == google.maps.GeocoderStatus.OK) {
// Center the map on the returned location
map.setCenter(results[0].geometry.location);
// Creating a new marker and adding it to the map
var myMarker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
draggable:true
});
document.getElementById('Latitude').value= results[0].geometry.location.lat();
document.getElementById('Longitude').value= results[0].geometry.location.lng();
google.maps.event.addListener(myMarker, 'dragend', function(evt){
document.getElementById('current').innerHTML = '<p>Marker dropped: Current Lat: ' + evt.latLng.lat().toFixed(3) + ' Current Lng: ' + evt.latLng.lng().toFixed(3) + '</p>';
});
google.maps.event.addListener(myMarker, 'dragstart', function(evt){
document.getElementById('current').innerHTML = '<p>Currently dragging marker...</p>';
});
map.setCenter(myMarker.position);
myMarker.setMap(map);
}
});
}
})();
I am new to Google maps development and I'm not even sure whether it's possible to achieve what I want. I've been working on this now for a few weeks and it's driving me a little crazy, so if someone could perhaps point me in the right direction it would gratefully be received.
Many thanks and kind regards
Chris
Instead of evt.latLng.lat().toFixed(3) you should just use the myMarker object and grab it's position.
Getting the nearest address is not that easy, but requires reverse geocoding, and to be honest I don't see the point in doing it. You would have to make special cases for the occurences where there couldn't be found a closest address and stuff like that.
If you really want to do it though there is a webservice you can call to do it.

Resources