Using Yandex map tiles in Google Maps v3 - google-maps-api-3

I have Yandex map tiles (Russian) working in Google Maps API v2 but something's not working in Google Maps API v3, see the following jsfiddle: http://jsfiddle.net/VkGjq/1/
Note that when switching between the Google road map and the Yandex tiles they don't line up & the marker is in the wrong position.
For Maps v2, I made an equivalent jsfiddle but it's broken since it needs an API key: http://jsfiddle.net/ggrgQ/1/
You can see similar code here, but you will have to navigate to Moscow manually as Yandex doesn't have any decent data outside of Russia: http://gpsloglabs.com/share/2367c16f3a0e75b05ac8a5529afba225dd929518/
I don't recall where I got the v3 code, but the constants appear to roughly correspond to the v2 version. Other than that, I don't understand what the projection is doing so I'm stuck.
Any ideas?
The code from the jsfiddle is as follows:
var center = new google.maps.LatLng(55.75, 37.62);
var mapOptions = {
zoom: 10,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
new google.maps.Marker({map: map, position: center});
map.mapTypes.set("Yandex",
new google.maps.ImageMapType(
{getTileUrl: function(coord, zoom) {
return "http://vec0"+((coord.x+coord.y)%5)+".maps.yandex.net/tiles?l=map&v=2.16.0&x=" +
coord.x + "&y=" + coord.y + "&z=" + zoom + "";
},
tileSize: new google.maps.Size(256, 256),
isPng: true,
alt: "Yandex",
name: "Yandex",
projection: new YandexProjection(),
maxZoom: 17}));
map.setOptions({mapTypeControlOptions: {mapTypeIds: [google.maps.MapTypeId.ROADMAP, "Yandex"]} });
function YandexProjection() {
this.pixelOrigin_ = new google.maps.Point(128,128);
var MERCATOR_RANGE = 256;
this.pixelsPerLonDegree_ = MERCATOR_RANGE / 360;
this.pixelsPerLonRadian_ = MERCATOR_RANGE / (2 * Math.PI);
this.fromLatLngToPoint = function(latLng) {
function atanh(x) {
return 0.5*Math.log((1+x)/(1-x));
}
function degreesToRadians(deg) {
return deg * (Math.PI / 180);
}
function bound(value, opt_min, opt_max) {
if (opt_min != null) value = Math.max(value, opt_min);
if (opt_max != null) value = Math.min(value, opt_max);
return value;
}
var origin = this.pixelOrigin_;
var exct = 0.0818197;
var z = Math.sin(latLng.lat()/180*Math.PI);
return new google.maps.Point(origin.x + latLng.lng() *this.pixelsPerLonDegree_,
Math.abs(origin.y - this.pixelsPerLonRadian_*(atanh(z)-exct*atanh(exct*z))));
};
this.fromPointToLatLng = function(point) {
var origin = this.pixelOrigin_;
var lng = (point.x - origin.x) / this.pixelsPerLonDegree_;
var latRadians = (point.y - origin.y) / -this.pixelsPerLonRadian_;
var lat = Math.abs((2*Math.atan(Math.exp(latRadians))-Math.PI/2)*180/Math.PI);
var Zu = lat/(180/Math.PI);
var Zum1 = Zu+1;
var exct = 0.0818197;
var yy = -Math.abs(((point.y)-128));
while (Math.abs(Zum1-Zu)>0.0000001){
Zum1 = Zu;
Zu = Math.asin(1-((1+Math.sin(Zum1))*Math.pow(1-exct*Math.sin(Zum1),exct))
/ (Math.exp((2*yy)/-(256/(2*Math.PI)))*Math.pow(1+exct*Math.sin(Zum1),exct)));
}
if (point.y>256/2) {
lat=-Zu*180/Math.PI;
} else {
lat=Zu*180/Math.PI;
}
return new google.maps.LatLng(lat, lng);
};
return this;
}

It turns out that the projection property can't be set via the ImageMapTypeOptions and has to be assigned after the ImageMapType has been constructed, this jsfiddle now works: http://jsfiddle.net/VkGjq/2/
var yandexMapType = new google.maps.ImageMapType(
{getTileUrl: function(coord, zoom) {
return "http://vec0"+((coord.x+coord.y)%5)+".maps.yandex.net/tiles?l=map&v=2.16.0&x=" +
coord.x + "&y=" + coord.y + "&z=" + zoom + "";
},
tileSize: new google.maps.Size(256, 256),
isPng: true,
alt: "Yandex",
name: "Yandex",
maxZoom: 17});
// projection is ignored if passed to MapTypeOptions
yandexMapType.projection = new YandexProjection();
map.mapTypes.set("Yandex", yandexMapType);

By license agreement you can't use yandex maps without yandex api. You can't use yandex tiles in leaflet.
You need to wrap yandex api or use http://leafletjs.com/plugins.html
Or write own a wrapper.
Example https://all-maps.herokuapp.com/
https://github.com/artamonovdev/all-maps

Related

Open Layers issue with markers changing coordinates

I have an issue that is driving me crazy. I have an openlayers map project that works fine. I took this concept code and moved it to a project that utilizes .Net and the projection for the markers/icons get messed up.
//set the Icon/Marker that will be used
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.8,
src: '<%=PinMarkerImage%>'
}))
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: iconStyle
});
//we will zoom the map to fit the locations after we create
//the map
var mapObj = new ol.Map({
layers: [new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer],
target: document.getElementById('map-canvas'),
view: new ol.View({
center: ol.proj.fromLonLat([0, 0]),
zoom: 12
})
});
alert(vectorSource.getExtent());
mapObj.getView().fit(vectorSource.getExtent(), { padding: [75, 40, 40, 75], constrainResolution: false });
//I pass in an object one at a time to populate the features
function changeMapOption(oBranch, i) {
// alert('selected');
var long = oBranch.Longitude;
var lat = oBranch.Latitude;
alert(long + ' ' + lat);
//lastCord = ol.proj.transform([coord[0], coord[1]], 'EPSG:4326', 'EPSG:3857');
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([long, lat], 'EPSG:4326', 'EPSG:3857')), //ol.proj.fromLonLat([long, lat])),
id: oBranch.Id,
title: oBranch.Name,
address: oBranch.Address + ", " + oBranch.City + ", " + oBranch.State + " " + oBranch.ZipCode
});
//alert(iconFeature.getGeometry());
vectorSource.addFeature(iconFeature);
//mapObj.getView().fit(vectorSource.getExtent(), { padding: [75, 40, 40, 75], constrainResolution: false });
//target = mapObj.getTarget();
//This will zoom the map to fit all of the vector Sources in vectorSource
//alert(vectorSource.getExtent());
//mapObj.addOverlay(popup);
//jTarget = typeof target === "string" ? $("#" + target) : $(target);
//element = document.getElementById('popup');
}
I have the alerts set to check the Longitude and Latitude. These are correct. For this test run I have three objects that are populated, the Longitude and Latitudes are as follows:
-112.04883, 40.492104
-95.673328, 29.95752
-95.638558, 29.880014
When I run the code the alert for the vectorSource.getExtent() produces this:
-12473218.699582075,-8426499.834030088,-10646435.576762961,-6361484.120029401
And the markers show up off the lower coast of Chile. The Latitude is wrong, yet the Longitude appears to be correct.
I could certainly use some guidance here. This is driving me crazy.
Thanks for any assistance.
After trying multiple times, I came up with a solution that works. Hopefully this will help someone down the line.
function loadMarker(oBranch, i) {
var sHTML = getMarkerInfoHtml(oBranch);
var long = oBranch.Longitude * 1;
var lat = oBranch.Latitude * 1;
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat(([long, lat]))),
index: oBranch.Id,
id: oBranch.Id,
title: oBranch.Name,
address: sHTML //oBranch.Address + ", " + oBranch.City + ", " + oBranch.State + " " + oBranch.ZipCode
});
vectorSource.addFeature(iconFeature);
}
The key was these two lines:
var long = oBranch.Longitude * 1;
var lat = oBranch.Latitude * 1;
by adding the * 1 to the line it forces JavaScript to treat the variables properly as numeric. It now places the markers in the correct location.

Unable to show csv data in d3.geo map

i am trying to show csv data in my map .The map i created from json data . But now it doesn't show any csv data but showing only json data.
tootip.html(" District :"+"\n" +d.id +d.Family_Feud_m)
here d.id 's "id" is from json file and d.Family_Feud_m's "Family_Feud_m" from csv file .
Here is my full js code:
var Districts=[];
var bardata = [];
var width = 500,
height = 700;
var scal = 5000;
var tootip = d3.select('body')
.append('div')
.style('position','absolute')
.style('padding','0 10px')
.style('background','white')
.style('opacity',0)
var projection = d3.geo.mercator()
.scale(scal)
.translate([-76.5/50.0 * scal, scal/2-scal/55]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select(".viewer")
.append("svg")
.attr("width", width)
.attr("height", height);
function redrawMap()
{
svg.selectAll(".subunit")
.style('fill',function(d){
amount = Districts[d.id];
if(amount == 0 || amount== undefined)
return 'rgba(0,0,0,0.5)';
return 'rgba(43,120,200,'+amount*1.0/10.0+')';
});
}
d3.csv('./data/resultsuicide.csv',function(data){
console.log(data)
for(key in data) {
bardata.push(data[key].value)
}
d3.json("./data/bd.json", function(error, bd) {
svg.selectAll(".subunit")
.data(topojson.feature(bd, bd.objects.subunits).features)
.enter().append("path")
.attr("class", function(d) { return "subunit " + d.id; })
.attr("d", path)
.on('mouseover',function(d){
tootip.transition()
.style('opacity',.9)
tootip.html(" District :"+"\n" +d.id +d.Family_Feud_m)
.style('left',(d3.event.pageX-35)+'px')
.style('top',(d3.event.pageY-30)+'px')
tempcolor = this.style.fill;
d3.select(this)
.style('opacity',.5)
.style('fill','green')
})
.on('mouseout',function(d){
d3.select(this)
.style('opacity',1)
.style('fill',tempcolor)
})
redrawMap();
});
});
//thanks in advance

Geocoder does not return the location properly

I have two arrays containing latitude and longtitude of 7 locations,and I use the following
code for getting the location of these 7 points:
var geocoder;
initialize();
codeLatLng();
function initialize() {
geocoder = new google.maps.Geocoder();
}
function codeLatLng() {
var arrlat=[45.95268273, 47.00196833,45.99168238, 46.2186456, 45.91612197, 45.91606814, 45.91606814];
var arrlon=[-66.68426012, -65.56480221, -63.98068545, -64.44419501, -66.74801471, -66.74810832, -66.74810832];
var input = document.getElementById("latlng").getAttribute('value');
console.log(input);
var latlngStr = input.split(",", 2);
var lat = parseFloat(latlngStr[0]);
var lng = parseFloat(latlngStr[1]);
for(var i=0;i<arrlat.length;i++)
{
var latlng = new google.maps.LatLng(arrlat[i], arrlon[i]);
geocoder.geocode({
'latLng': latlng
}, function(results, status) {
//document.getElementById("test").innerHTML = '' + (results[4].formatted_address); + ''
alert(results[4].formatted_address);
});
}
}
whenever I feed the arrays with 5 of less elements the code works properly but for more than 5 I get 5 alert showing the location of the first 5 elements but for the last 2 I get the following error:
Uncaught TypeError: Cannot read property '4' of null
And here is the Jfiddle link:
link
Can anyone help?
Code more defensively. Check the status of the response before using it. If it isn't "OK", there won't be any results to process.
function codeLatLng() {
var arrlat=[45.95268273, 47.00196833,45.99168238, 46.2186456, 45.91612197, 45.91606814, 45.91606814];
var arrlon=[-66.68426012, -65.56480221, -63.98068545, -64.44419501, -66.74801471, -66.74810832, -66.74810832];
var input = document.getElementById("latlng").getAttribute('value');
console.log(input);
var latlngStr = input.split(",", 2);
var lat = parseFloat(latlngStr[0]);
var lng = parseFloat(latlngStr[1]);
for(var i=0;i<arrlat.length;i++)
{
var latlng = new google.maps.LatLng(arrlat[i], arrlon[i]);
geocoder.geocode({
'latLng': latlng
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK ) {
//document.getElementById("test").innerHTML = '' + (results[4].formatted_address); + ''
if (results.length >= 5)
alert(results[4].formatted_address);
else alert("less than 5 results");
} else alert("reverse geocode failed, status="+status);
});
}
}
See the documentation on Status Codes for what the failure codes mean.

Fail with Fusion table when using google.visualization.Query (test1 successed but similar test2 failed)

The code below is used to make google-fusion-table work with markercluster together.
(referrence: http://www.cs.gsu.edu/~ashrestha2/vis/prjmap2.html
Give honor to the author very much)
However, when I was trying to follow the example in the above link, I succeed in test 1 but failed in test 2. The test 1 used a fusion table with two columns and the test 2 used a fusion table with three columns. I don't know why I failed as I only added one more column for test 2.
google.load('visualization', '1.0', {"callback":initialize});
//var tableid = '1_6G1c1l7glLHRuOU7uvH8oONbObDf_cOtZS21Rc', atlcenter = new google.maps.LatLng(33.755711,-84.388372); //test1_success
var tableid = '1IagEEylcnbuPygCES70ipnvb9q0C5OgmGPNyx9o1', atlcenter = new google.maps.LatLng(33.755711,-84.388372); //test2_fail
var mapMain, markers, dataTable = null, mc = null;
function initialize() {
mapMain = new google.maps.Map(document.getElementById('map-canvas'), {
center: atlcenter,
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
mc = new MarkerClusterer(mapMain);
queryMap("select * from "+tableid);
}
function queryMap(queryText){
mc.clearMarkers(); markers=[];
var tmp = 'http://www.google.com/fusiontables/gvizdata?tq='+encodeURIComponent(queryText);
var query = new google.visualization.Query(tmp);
query.send(handleQueryResponse);
}
function handleQueryResponse(response){
dataTable = response.getDataTable();
alert(response.isError());
for(var i=0; i< dataTable.getNumberOfRows();i++){
var hrefval = dataTable.getValue(i,0).toString();
var arr = dataTable.getValue(i,1).toString().split(" ");
var latlng = new google.maps.LatLng(arr[0], arr[1]);
var marker = new google.maps.Marker({
position: latlng,
map:mapMain
});
markers.push(marker);
}
mc.addMarkers(markers);
}
This encrypted id is not valid:
1IagEEylcnbuPygCES70ipnvb9q0C5OgmGPNyx9o1
https://www.google.com/fusiontables/DataSource?docid=1IagEEylcnbuPygCES70ipnvb9q0C5OgmGPNyx9o1

Google Maps API: Uncaught TypeError: Cannot read property '__e3_' of undefined

I'm currently use a new system for my weather website and I'm getting the following error:
Uncaught TypeError: Cannot read property '__e3_' of undefined
Xe%7Bmain,places,weather%7D.js:18
Ve%7Bmain,places,weather%7D.js:21
P.addListener%7Bmain,places,weather%7D.js:18
T.(anonymous function).bindTo%7Bmain,places,weather%7D.js:27
initializejavascript.js:109
(anonymous function)javascript.js:4
f.Callbacks.ojquery.min.js:2
f.Callbacks.p.fireWithjquery.min.js:2
e.extend.readyjquery.min.js:2
c.addEventListener.B
Here's the content in my javascript.js file which I include in my header.php (<script src="javascript.js" type="text/javascript"></script>):
$(document).ready(function() {
initialize();
});
var elevator;
var geocoder;
var map;
function initialize() {
// KONFIGURATION: Geocoding
geocoder = new google.maps.Geocoder();
// KONFIGURATION: Filnamn
var weatherdata = 'fetch-information/fetch-weatherdata.php';
// KONFIGURATION: Datum
var date = new Date();
var datetime = date.getFullYear() + '-' +
(date.getMonth() < '10' ? '0' + date.getMonth() : date.getMonth()) + '-' +
(date.getDay() < '10' ? '0' + date.getDay() : date.getDay()) + ', ' +
(date.getHours() < '10' ? '0' + date.getHours() : date.getHours()) + ':' +
(date.getMinutes() < '10' ? '0' + date.getMinutes() : date.getMinutes()) + ':' +
(date.getSeconds() < '10' ? '0' + date.getSeconds() : date.getSeconds());
// KONFIGURATION: Hämta adress
var address = 'Karlstad, Sverige';
// KONFIGURATION: Inställningar för kartan
var myOptions = {
streetViewControl: false,
overviewMapControl: true,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// MOLNAKTIVITET
var cloudLayer = new google.maps.weather.CloudLayer();
cloudLayer.setMap(map);
/**********************************************
** THE CODE BELOW IS CAUSING THE ERROR **
**********************************************/
// HÖJD ÖVER / UNDER HAVSYTAN
elevator = new google.maps.ElevationService();
google.maps.event.addListener(map, 'click', getElevation);
/* ** ** ** ** ** */
// GOOGLE PLACES API
var input = document.getElementById('googlemaps-search');
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var place = autocomplete.getPlace();
alert(place.geometry.location);
});
/**********************************************
** THE CODE ABOVE IS CAUSING THE ERROR **
**********************************************/
/* ** ** ** ** ** */
// GEOCODING
geocoder.geocode({'address' : address}, function(results, status) {
// KONTROLL
if(status == google.maps.GeocoderStatus.OK) {
// KONFIGURATION: Ta bort ( och ) före och efter koordinaterna
var old_latlong = '' + results[0].geometry.location + '';
var new_latlong = old_latlong.substring(1, old_latlong.length - 1).replace(' ', '');
// CENTERRING
map.setCenter(results[0].geometry.location);
// MARKERING: Adress
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
// AJAX: Hämta den angivna filen
$.ajax({
url: weatherdata + '?coordinates=' + new_latlong,
success: function() {
console.log(datetime + ': Hämtningen av väderprognosen och den övriga informationen lyckades');
$('.content-search').show();
$('#load-weather').load(weatherdata + '?coordinates=' + new_latlong);
},
error: function() {
console.error(datetime + ': Hämtningen av väderprognosen och den övriga informationen misslyckades');
$('#load-weather').hide();
$('.content-search').hide();
$('#message-error').show();
}
});
// KONTROLL
} else {
// FELMEDDELANDE
alert('Kunde inte hämta data på grund av följande fel: ' + status);
}
});
/* ** ** ** ** ** */
// KARTA
var map = new google.maps.Map(document.getElementById('weather-map'), myOptions);
}
/** ** ** ** ** ** ** ** ** ** ** ** **/
function getElevation(event) {
var locations = [];
var clickedLocation = event.latLng;
locations.push(clickedLocation);
var positionalRequest = {
'locations': locations
}
elevator.getElevationForLocations(positionalRequest, function(results, status) {
if(status == google.maps.ElevationStatus.OK) {
var s = results[0].elevation;
if(results[0]) {
if(('' + parseInt(s)).charAt(0) == '-') {
$('#elevation').html('Cirka ' + number_format(('' + parseInt(s)).substring(1)) + ' meter under havsytan');
} else {
$('#elevation').html('Cirka ' + number_format(parseInt(s)) + ' meter över havsytan');
}
} else {
alert('Inget resultat hittades');
}
} else {
alert('Det gick inte att hitta höjdskillnaden på grund av följande: ' + status);
}
});
}
The problem is that the system is quite the same as in my previous system and I have the same "code structure" on both of them and still I'm getting this error message on the new system. I don't know why I'm getting it so I'm asking you know: how can I fix my problem?
Thanks in advance.
When I moved the map definition to a point before the marked buggy code, it worked. I added the var map = new google.map.Map to right after the map options.
var myOptions = {
streetViewControl: false,
overviewMapControl: true,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('weather-map'), myOptions);
// MOLNAKTIVITET
var cloudLayer = new google.maps.weather.CloudLayer();
cloudLayer.setMap(map);
/**********************************************
** THE CODE BELOW IS CAUSING THE ERROR **
**********************************************/
// HÖJD ÖVER / UNDER HAVSYTAN
elevator = new google.maps.ElevationService();
google.maps.event.addListener(map, 'click', getElevation);

Resources