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
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.
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
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.
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
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);