i'm making an android app with cordova. And a I have a noob problem.
I have a map in the index.html, when the index initializes the app obtains the position of the mobile and later does a map with a marker where the mobile is.
The code is this:
var longitud;
var latitud;
function getPosition() {
var options = {
enableHighAccuracy: true,
maximumAge: 1
}
var watchID = navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
function onSuccess(position) {
this.latitud = position.coords.latitude;
this.longitud = position.coords.longitude;
navigator.geolocation.clearWatch(watchID);
mapa();
};
function onError(error) {
alert('code: ' + error.code + '\n' + 'message: ' + error.message + '\n');
}
}
function mapa() {
alert(this.latitud + ' ' + this.longitud);
document.getElementById("mapa").innerHTML = "";
map = new OpenLayers.Map("mapa");
var mapnik = new OpenLayers.Layer.OSM();
var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
var position = new OpenLayers.LonLat(window.longitud, window.latitud).transform(fromProjection, toProjection);
var zoom = 17;
map.addLayer(mapnik);
map.setCenter(position, zoom);
var lonLat = new OpenLayers.LonLat(this.longitud, this.latitud)
.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
var markers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(markers);
//markers.icon(img/ico-taxi);
markers.addMarker(new OpenLayers.Marker(lonLat));
}
This works well in the index.html. But in other page i want to do the same thing, but instead of showing always, only show it if the users click the accordion because the users must know where are they but I dont want to have a big map in this page all time. When user open the accordion the app creates a map using the same functions because the div id is the same. This works well too, but additionally i want to put the coordinates inside two inputs: inputLat and Input Lon. When user click the accordion in the inputs appears undefined but in theory were defined in index.html and when he clicks in the accordion. But the most strange thing is that, when I close the accordion and I open it again, the coordinates appears. How I can have the coordinates in the input the first time i clik accordion? I give you the code of the accordion functions.
function comprobar() {
var x = document.getElementById("mapa");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
getPosition();
geoLocalizacion();
} else {
x.className = x.className.replace(" w3-show", "");
}
}
function geoLocalizacion () {
document.getElementById("inputLat").value = this.latitud;
document.getElementById("inputLon").value = this.longitud;
}
I tried to read other similar posts and doesn't work. If I add var Longitud = this; int the declaration it shows [object Window]
javascript returns undefind for a globally declared variable
Why a variable defined global is undefined?
Thanks to all I'm so sure that is a noob thing.
Related
I need to display different polylines from A to B. So, these lines should be distinguishable from each other. I haved tried to set polylines using pushpoint function with altitude parameter. However it is still on the ground level. And the last polyline I inserted overwrites the previous one.
Altitude value works on markers but I want to apply it on polyline.
I changed the sample code here markers with altitude as below. You can see the orange line is just on top of the gray line when you change the code with the below one. I would like both lines to be displayed like the markers you see above them.
/**
* Calculate the bicycle route.
* #param {H.service.Platform} platform A stub class to access HERE services
*/
function calculateRouteFromAtoB (platform) {
var router = platform.getRoutingService(),
routeRequestParams = {
mode: 'fastest;bicycle',
representation: 'display',
routeattributes : 'shape',
waypoint0: '-16.1647142,-67.7229166',
waypoint1: '-16.3705847,-68.0452683',
// explicitly request altitude values
returnElevation: true
};
router.calculateRoute(
routeRequestParams,
onSuccess,
onError
);
}
/**
* Process the routing response and visualise the descent with the help of the
* H.map.Marker
*/
function onSuccess(result) {
var lineString = new H.geo.LineString(),
lineString2 = new H.geo.LineString(),
routeShape = result.response.route[0].shape,
group = new H.map.Group(),
dict = {},
polyline,
polyline2;
routeShape.forEach(function(point) {
var parts = point.split(',');
var pp= new H.geo.Point(parts[0],parts[1],4000,"SL");
console.log(parts[2]);
lineString.pushLatLngAlt(parts[0], parts[1]);
lineString2.pushPoint(pp);
// normalize the altitude values for the color range
var p = (parts[2] - 1000) / (4700 - 1000);
var r = Math.round(255 * p);
var b = Math.round(255 - 255 * p);
// create or re-use icon
var icon;
if (dict[r + '_' + b]) {
icon = dict[r + '_' + b];
} else {
var canvas = document.createElement('canvas');
canvas.width = 4;
canvas.height = 4;
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(' + r + ', 0, ' + b + ')';
ctx.fillRect(0, 0, 4, 4);
icon = new H.map.Icon(canvas);
// cache the icon for the future reuse
dict[r + '_' + b] = icon;
}
// the marker is placed at the provided altitude
var marker = new H.map.Marker({
lat: parts[0], lng: parts[1], alt: parts[2]
}, {icon: icon});
var marker2 = new H.map.Marker({
lat: parts[0], lng: parts[1], alt: parts[2]-800
}, {icon: icon});
group.addObject(marker);
group.addObject(marker2);
});
polyline = new H.map.Polyline(lineString, {
style: {
lineWidth: 6,
strokeColor: '#555555'
}
});
polyline2 = new H.map.Polyline(lineString2, {
style: {
lineWidth: 3,
strokeColor: '#FF5733'
}
});
// Add the polyline to the map
map.addObject(polyline);
map.addObject(polyline2);
// Add markers to the map
map.addObject(group);
// Zoom to its bounding rectangle
map.getViewModel().setLookAtData({
bounds: polyline.getBoundingBox(),
tilt: 60
});
}
/**
* This function will be called if a communication error occurs during the JSON-P request
* #param {Object} error The error message received.
*/
function onError(error) {
alert('Can\'t reach the remote server');
}
/**
* Boilerplate map initialization code starts below:
*/
// set up containers for the map + panel
var mapContainer = document.getElementById('map'),
routeInstructionsContainer = document.getElementById('panel');
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();
//Step 2: initialize a map - this map is centered over Berlin
var map = new H.Map(mapContainer,
defaultLayers.vector.normal.map,{
center: {lat:52.5160, lng:13.3779},
zoom: 13,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
// Now use the map as required...
calculateRouteFromAtoB (platform);
Unfortunately, for now only markers support altitudes.
Polylines should follow in near future.
is there any chance to set the rotation for a marker? For now, I set the map bearing to the angle of one marker, but the others should have their own marker bearing.
At the moment, I'm using the marker definition like so:
var marker_el = document.createElement('div');
marker_el .className = 'marker';
var new_marker = new mapboxgl.Marker(marker_el)
.setPopup(marker_PopUp);
and set it to the map:
new_marker.setLngLat([lon, lat]);
new_marker.addTo(map);
I'm using JS and react and for the map mapbox-gl
so because there are no answers, I self answer my post with a working solution for me:
var angle = "yourAngle";
var rotateString = "rotate(" + angle + "deg)";
var marker_el = document.createElement('div');
marker_el.className = 'marker';
var new_marker = new mapboxgl.Marker(marker_el);
new_marker.addTo(map);
/* important here is to append the rotate property because the transform
property is already being updated */
marker_el.style.transform = marker_el.style.transform + rotateString;
I am trying to "move" renderables around the web worldwind globe on an interval. To illustrate the issue I am having, I made a small example.
This works (but is inefficient):
var myVar = setInterval(myTimer, 5000);
function myTimer() {
shapesLayer.removeRenderable(shape);
shape = new WorldWind.SurfaceCircle(new WorldWind.Location(shape.center.latitude+1, shape.center.longitude), 200e3, attributes);
shapesLayer.addRenderable(shape);
console.log(" new pos "+shape.center.latitude + " "+shape.center.longitude);
wwd.redraw();
}
This is what I'd like to do, but the shape doesn't move:
var myVar = setInterval(myTimer, 5000);
function myTimer() {
shape.center = new WorldWind.Location(shape.center.latitude+1, shape.center.longitude);
console.log(" new pos "+shape.center.latitude + " "+shape.center.longitude);
wwd.redraw();
}
Is there a flag I need to set on the renderable to make it refresh?
Here is the full SurfaceShapes.js file I've been playing with (based on this http://worldwindserver.net/webworldwind/examples/SurfaceShapes.html):
/*
* Copyright (C) 2014 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration. All Rights Reserved.
*/
/**
* Illustrates how to display SurfaceShapes.
*
* #version $Id: SurfaceShapes.js 3320 2015-07-15 20:53:05Z dcollins $
*/
requirejs(['../src/WorldWind',
'./LayerManager'],
function (ww,
LayerManager) {
"use strict";
// Tell World Wind to log only warnings.
WorldWind.Logger.setLoggingLevel(WorldWind.Logger.LEVEL_WARNING);
// Create the World Window.
var wwd = new WorldWind.WorldWindow("canvasOne");
/**
* Added imagery layers.
*/
var layers = [
{layer: new WorldWind.BMNGLayer(), enabled: true},
{layer: new WorldWind.BingAerialWithLabelsLayer(null), enabled: true},
{layer: new WorldWind.CompassLayer(), enabled: true},
{layer: new WorldWind.CoordinatesDisplayLayer(wwd), enabled: true},
{layer: new WorldWind.ViewControlsLayer(wwd), enabled: true}
];
for (var l = 0; l < layers.length; l++) {
layers[l].layer.enabled = layers[l].enabled;
wwd.addLayer(layers[l].layer);
}
// Create a layer to hold the surface shapes.
var shapesLayer = new WorldWind.RenderableLayer("Surface Shapes");
wwd.addLayer(shapesLayer);
// Create and set attributes for it. The shapes below except the surface polyline use this same attributes
// object. Real apps typically create new attributes objects for each shape unless they know the attributes
// can be shared among shapes.
var attributes = new WorldWind.ShapeAttributes(null);
attributes.outlineColor = WorldWind.Color.BLUE;
attributes.drawInterior = false;
attributes.outlineWidth = 4;
attributes.outlineStippleFactor = 1;
attributes.outlineStipplePattern = 0xF0F0;
var highlightAttributes = new WorldWind.ShapeAttributes(attributes);
highlightAttributes.interiorColor = new WorldWind.Color(1, 1, 1, 1);
// Create a surface circle with a radius of 200 km.
var shape = new WorldWind.SurfaceCircle(new WorldWind.Location(35, -120), 200e3, attributes);
shape.highlightAttributes = highlightAttributes;
shapesLayer.addRenderable(shape);
// Create a layer manager for controlling layer visibility.
var layerManger = new LayerManager(wwd);
// Now set up to handle highlighting.
var highlightController = new WorldWind.HighlightController(wwd);
var myVar = setInterval(myTimer, 5000);
function myTimer() {
//Shape doesn't move
shape.center = new WorldWind.Location(shape.center.latitude+1, shape.center.longitude);
//Shape "moves" but is inefficient
//shapesLayer.removeRenderable(shape);
//shape = new WorldWind.SurfaceCircle(new WorldWind.Location(shape.center.latitude+1, shape.center.longitude), 200e3, attributes);
//shapesLayer.addRenderable(shape);
console.log(" new pos "+shape.center.latitude + " "+shape.center.longitude);
wwd.redraw();
}
}
);
Document says renderables variable is readonly but I think it can be possible.
change code
shape.center = new WorldWind.Location(shape.center.latitude+1, shape.center.longitude);
To
index = ShapesLayer.renderables.indexOf(shape);
ShapesLayer.renderables[index].center = new WorldWind.Location(shape.center.latitude+1, shape.center.longitude);
I think ShapesLayer.addRenderable create anther shape.
If you think it's not good way to do you can use this way
RenderableLayer.prototype.changeRenderable= function (prevRenderable, nextRenderable) {
index = ShapesLayer.renderables.indexOf(prevRenderable);
ShapesLayer.renderables[index].center = nextRenderable;
};
main code
ShapesLayer.changeRenderable(shape, new WorldWind.Location(shape.center.latitude+1, shape.center.longitude));
Document : https://nasaworldwind.github.io/WebWorldWind/layer_RenderableLayer.js.html
If anyone else is looking at this, I found a better solution to force it to recompute the center position by setting isPrepared to false and _boundaries to undefined.
var myVar = setInterval(myTimer, 5000);
function myTimer() {
shape.isPrepared = false;
shape._boundaries = undefined;
shape.center = new WorldWind.Location(shape.center.latitude+1, shape.center.longitude);
console.log(" new pos "+shape.center.latitude + " "+shape.center.longitude);
wwd.redraw();
}
I am having a few issues with the Google Maps API. I managed to make a cutom map using an image tile. which seems to be working OK. I am just wondering if there is a way to overlay roads on the map?
At the moment I am assuming there are 2 ways this is possible, either some built in function in the API, which I am having troubles finding. I have found paths etc, But I would like roads/streets to have labels, resize on zoom etc, as well as be able to toggle.
The other option was to do a second image tile and overlay that image, which I am not sure how todo at this moment.
If anyone has any info on this, or could point me in the right direction. It would be much appreciated.
/* <![CDATA[ */
/* Global variable that will contain the Google Maps object. */
var map = null
// Google Maps Demo object
var Demo = Demo || {};
// The path to your tile images.
Demo.ImagesBaseUrl = './mapImage/mapTiles/';
Demo.ImagesRoadsUrl = './mapImage/overlayRoads/';
// NuviaMap class
Demo.NuviaMap = function(container) {
// Create map
// This sets the default info for your map when it is initially loaded.
map = new google.maps.Map(container, {
zoom: 1,
center: new google.maps.LatLng(0, 0),
mapTypeControl: false,
streetViewControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
}
});
// Set custom tiles
map.mapTypes.set('nuvia', new Demo.ImgMapType('nuvia', '#4E4E4E'));
map.setMapTypeId('nuvia');
// Loop through the marker info array and load them onto the map.
for (var key in markers) {
var markerData = markers[key];
var marker = new google.maps.Marker({
position: new google.maps.LatLng(markerData.lat, markerData.lng),
map: map,
title: markerData.title,
flat: markerData.flat,
visible: true,
infoBubble: new InfoBubble({
maxWidth: 300,
content: (markerData.image ? '<img src="' + markerData.image + '" width="80" align="left">' : '') + '<h3>' + markerData.title + '</h3>' + (markerData.info ? '<p>' + markerData.info + '</p>' : ''),
shadowStyle: 1,
padding: '10px'
}),
// You can use custom icons, default icons, etc. In my case since a city was a marker the circle icon works pretty well.
// I adjust the scale / size of the icon depending on what kind of city it is on my map.
icon: {
url: markerData.icon,
}
});
// We need to trap the click event for the marker so we can pop up an info bubble.
google.maps.event.addListener(marker, 'click', function() {
this.infoBubble.open(map, this);
});
activeMarkers.push(marker);
}
// This is dumb. We only want the markers to display at certain zoom levels so this handled that.
// Google should have a way to specify zoom levels for markers. Maybe they do but I could not find them.
google.maps.event.addListener(map, 'zoom_changed', function() {
var currentZoom = map.getZoom();
for (var i = 0; i < activeMarkers.length; i++) {
var thisTitle = activeMarkers[i].title;
if (markers[thisTitle]['zoom'][currentZoom])
activeMarkers[i].setVisible(true);
else
activeMarkers[i].setVisible(false);
}
});
// This handles the displaying of lat/lng info in the lat/lng info container defined above in the HTML.
google.maps.event.addListener(map, 'click', function(event) {
$('#latLng').html("Latitude: " + event.latLng.lat() + " " + ", longitude: " + event.latLng.lng());
});
// Listener to display the X/Y coordinates
google.maps.event.addListener(map, 'mousemove', function (event) {
displayCoord(event.latLng);
});
};
// ImgMapType class
Demo.ImgMapType = function(theme, backgroundColor) {
this.name = this._theme = theme;
this._backgroundColor = backgroundColor;
};
// Let Google know what size our tiles are and what our min/max zoom levels should be.
Demo.ImgMapType.prototype.tileSize = new google.maps.Size(256, 256);
Demo.ImgMapType.prototype.minZoom = 1;
Demo.ImgMapType.prototype.maxZoom = 5;
// Load the proper tile.
Demo.ImgMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
var tilesCount = Math.pow(2, zoom);
if (coord.x >= tilesCount || coord.x < 0 || coord.y >= tilesCount || coord.y < 0) {
var div = ownerDocument.createElement('div');
div.style.width = this.tileSize.width + 'px';
div.style.height = this.tileSize.height + 'px';
div.style.backgroundColor = this._backgroundColor;
return div;
}
var img = ownerDocument.createElement('IMG');
img.width = this.tileSize.width;
img.height = this.tileSize.height;
// This tells what tile image to load based on zoom and coord info.
img.src = Demo.Utils.GetImageUrl('tile_' + zoom + '_' + coord.x + '-' + coord.y + '.png');
return img;
};
// Just basically returns the image using the path set way above and the name of the actual image file.
Demo.Utils = Demo.Utils || {};
Demo.Utils.GetImageUrl = function(image) {
return Demo.ImagesBaseUrl + image;
};
// Opacity.
Demo.Utils.SetOpacity = function(obj, opacity /* 0 to 100 */ ) {
obj.style.opacity = opacity / 100;
obj.style.filter = 'alpha(opacity=' + opacity + ')';
};
// Create ye ol' map.
google.maps.event.addDomListener(window, 'load', function() {
var nuviaMap = new Demo.NuviaMap(document.getElementById('nuvia-map'));
});
console.log('Ready Builder');
/* ]]> */
This is the JS I am working off so far, (Credits to http://www.cartographersguild.com/showthread.php?t=21088)
I've made the code so that I get yellow points on my map, the coords and some other facts is loaded from a external file.
Here's the resource file
var sites = [{id:1269209,geometry:{ type:"Point",lat:1,lon: 1},properties:{siteName:"Yttern",parentId:1269209,siteType:2}}];
And here's the script for viewing them
var vectorLayer = new OpenLayers.Layer.Vector("Overlay");
$.getScript('test.js',function(){
for(var i = 0; i < sites.length; i++)
{
var site = sites[i];
var feature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(site.geometry.lon,site.geometry.lat));
vectorLayer.addFeatures(feature);
}
map.addLayer(vectorLayer);
});
The thing I woundering about is how do I do to make a hoverable popup for each marker, with the content from the JSON file?
Is it also possible to make the request only when the user have passed zoom level 14?
Now, I've fixed the function that starts when zoom passed 10
map.events.register("moveend", null, function(){
if(map.zoom >= 10)
{
var bounds = map.getExtent();
var ne = new OpenLayers.LonLat(bounds.right,bounds.top).transform(map.getProjectionObject(),new OpenLayers.Projection("EPSG:4326"));
var sw = new OpenLayers.LonLat(bounds.left,bounds.bottom).transform(map.getProjectionObject(),new OpenLayers.Projection("EPSG:4326"));
var vectorLayer = new OpenLayers.Layer.Vector("Layer");
$.getScript('ajax.php?a=markers&type=javascript&sw=('+sw.lon+','+sw.lat+')&ne=('+ne.lon+','+ne.lat+')',function(){
//$.getScript('test.js',function(){
for(var i = 0; i < sites.length; i++)
{
var site = sites[i];
var latlon = new OpenLayers.LonLat(site.geo.lon,site.geo.lat);
var feature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(latlon)
);
vectorLayer.addFeatures(feature);
}
map.addLayer(vectorLayer);
});
}
});
but still I dont get the markers on the map, is something wrong?
One result from markers.php aka ajax.php?a=markers....
var sites = [{siteId:'9',siteName:'Hårleby',geo:{lon:11.641452694427471,lat:58.15782686109065},fact:{parentSiteId:0,county:'Orust'}}];
is it the projection on the result maybe? Please help.