I'm attempting to create a mobile app with the following purposes:
1. display geolocation with watchpostion so that the location marker moves with you across the map.
2. display markers with interactive* infowindows along the map wich are at solid locations.
3. have direction availability so that it shows the route from geolocation to position of the marker of your choice.
* with interactive I mean I wish for the marker to contain an import from database function. The database will display the current price of the Product of interest available on the various markerpoints within the chosen zoom-area and highlight the marker with the lowest price so that you may select to gt direction to the location with the best offer.
I have been able to create the watchposition() map itself and creating an infowindow displaying on a fixed map. However those two are working in to individual Projects, but when I try to put them together the preview goes blank. How to make them work together? I'm using myeclipse 2015 stable version
Here is the code for geolocation I wish to add markers in:
<!DOCTYPE HTML>
<html>
<head>
<title>Geolocation watchPosition()</title>
<!-- for mobile view -->
<meta content='width=device-width, initial-scale=1' name='viewport'/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" > </script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false&language=en"></script>
<script type="text/javascript">
// you can specify the default lat long
var map,
currentPositionMarker,
mapCenter = new google.maps.LatLng(57.736585899999994, 12.956377999999999),
map;
// change the zoom if you want
function initializeMap()
{
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 18,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
function locError(error) {
// tell the user if the current position could not be located
alert("The current position could not be found!");
}
// current position of the user
function setCurrentPosition(pos) {
currentPositionMarker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
),
title: "Current Position"
});
map.panTo(new google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
));
}
function displayAndWatch(position) {
// set current position
setCurrentPosition(position);
// watch position
watchCurrentPosition();
}
function watchCurrentPosition() {
var positionTimer = navigator.geolocation.watchPosition(
function (position) {
setMarkerPosition(
currentPositionMarker,
position
);
});
}
function setMarkerPosition(marker, position) {
marker.setPosition(
new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude)
);
}
function initLocationProcedure() {
initializeMap();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(displayAndWatch, locError);
} else {
// tell the user if a browser doesn't support this amazing API
alert("Your browser does not support the Geolocation API!");
}
}
// initialize with a little help of jQuery
$(document).ready(function() {
initLocationProcedure();
});
</script>
<!-- display the map here, you can changed the height or style -->
<div id="map_canvas" style="height:25em; margin:0; padding:0;"></div>
Related
I am generating an HTML/Javascript file from an Access365 database which plots pins on a Bing Map. Each of the pins has associated metadata about the location it is pinning which is viewed by clicking the pin. However, there can be pins which are at exactly the same location (lat and long) and only the metadata for the top pin is available.
How do I either show the combined metadata or have the pins move apart a bit say when the the user mouses over them? Does anyone know how to do that? I've gone round in circles looking at the MS documentation and can't find anything to help.
P.S. There is also a clusterLayer. If that needs removing to solve the problem that's Ok but it would be better if it could stay.
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<!-- Reference to the Bing Maps SDK -->
<script type='text/javascript'
src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=[zzz]'
async defer></script>
<script type='text/javascript'>
function GetMap()
{
var map = new Microsoft.Maps.Map('#myMap', {center: new Microsoft.Maps.Location(53.50632, -7.2714), zoom:8});
var ourBlue = 'rgb(108, 162, 212)';
//Create an infobox at the center of the map but don't show it.
infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
visible: false
});
//Assign the infobox to a map instance.
infobox.setMap(map);
var theLocations = [3];
var thePins = [3];
theLocations[0] = new Microsoft.Maps.Location(53.41, -7.1);
theLocations[1] = new Microsoft.Maps.Location(53.42, -7.1);
theLocations[2] = new Microsoft.Maps.Location(53.43, -7.1);
for (var i = 0; i < theLocations.length; i++){
var pin = new Microsoft.Maps.Pushpin(theLocations[i]);
pin.metadata = {
title: 'Pin ' + i, description: 'Description for pin' + i
};
Microsoft.Maps.Events.addHandler(pin, 'click', pushpinClicked);
Microsoft.Maps.Events.addHandler(pin, 'mouseover', splitOverlap);
Microsoft.Maps.Events.addHandler(pin, 'mouseout', function (e) {
e.target.setOptions({ color:'purple' });
});
thePins[i] = pin; //add pin to array of pins
}
Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function(){
clusterLayer = new Microsoft.Maps.ClusterLayer(thePins);
map.layers.insert(clusterLayer);
});
}
function splitOverlap(e) {
var ourBlue = 'rgb(108, 162, 212)';
e.target.setOptions({color:ourBlue});
}
}
function pushpinClicked(e) {
//Make sure the infobox has metadata to display.
if (e.target.metadata) {
//Set the infobox options with the metadata of the pushpin.
infobox.setOptions({
location: e.target.getLocation(),
title: e.target.metadata.title,
description: e.target.metadata.description,
visible: true
});
}
}
</script>
<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=Arvr3LDJsmNB-2OGHl_egpbP9RbwsYKGKrktnPBC06G38T9q3CzsfmwK6GNoW7R_' async defer></script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;"></div>
</body>
</html>
When you have clusters and you want to see individual metadate for items within the cluster there are two common approaches:
Have a popup that shows the first location metadata and buttons to step/page/tab through each item in the cluster.
Use the spider cluster visualization: https://bingmapsv8samples.azurewebsites.net/#Clustering_SpiderClusters
I am just starting with Bing map. Gone through few examples in official documentation.
Example from Bing map V8 official documentation
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script type='text/javascript'
src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
<script type="text/javascript">
var map, clusterLayer;
function GetMap() {
map = new Microsoft.Maps.Map('#myMap',{
credentials: 'Your Bing Maps Key',
zoom: 3
});
Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
//Generate 3000 random pushpins in the map view.
var pins = Microsoft.Maps.TestDataGenerator.getPushpins(3000, map.getBounds());
//Create a ClusterLayer with options and add it to the map.
clusterLayer = new Microsoft.Maps.ClusterLayer(pins, {
clusteredPinCallback: customizeClusteredPin
});
map.layers.insert(clusterLayer);
});
}
function customizeClusteredPin(cluster) {
//Add click event to clustered pushpin
Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
}
function clusterClicked(e) {
if (e.target.containedPushpins) {
var locs = [];
for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
//Get the location of each pushpin.
locs.push(e.target.containedPushpins[i].getLocation());
}
//Create a bounding box for the pushpins.
var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);
//Zoom into the bounding box of the cluster.
//Add a padding to compensate for the pixel area of the pushpins.
map.setView({ bounds: bounds, padding: 100 });
}
}
</script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;"></div>
</body>
</html>
In above bing map cluster example how to replace the TestDataGenerator data with realtime data JSON like below
mapData = [{"Name":"Point: 0","Latitude":22.0827,"Longitude":80.2707},
{"Name":"Point: 1","Latitude":24.0827,"Longitude":80.2707},
{"Name":"Point: 2","Latitude":26.0827,"Longitude":80.2707},
{"Name":"Point: 3","Latitude":28.0827,"Longitude":80.2707},
{"Name":"Point: 4","Latitude":20.0827,"Longitude":80.2707},
{"Name":"Point: 5","Latitude":22.0827,"Longitude":82.2707},
{"Name":"Point: 6","Latitude":30.0827,"Longitude":80.2707},
{"Name":"Point: 7","Latitude":22.0827,"Longitude":84.2707},
{"Name":"Point: 8","Latitude":32.0827,"Longitude":84.2707},
{"Name":"Point: 9","Latitude":18.0827,"Longitude":80.2707}];
When I pass above object in ClusterLayer I am getting following error
Uncaught TypeError: i[t].getLocation is not a function(…)
You have to loop through your data and turn it into pushpins. Here's a code sample:
var pins = [];
for(var i = 0;i < mapData.length;i++){
var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));
//Store the original data object in the pushpins metadata so that you can access other properties like Name.
pin.metedata = mapData[i];
pins.push(pin);
}
//Now "pins" is an array of pushpins. Add them to the map or to the clustering layer.
I get stuck when try to insert a demo of three.js tutorial into the view of CakePHP,
This demo (creating a scene): enter link description here
Has anybody try it like that ?
Thanks for reading . I hope you share your experiments.
Detail my problems:
I create webgl_test.js and put it into ...webroot/js/, and also put the three.min.js into webroot/js/
//------------- CREATING THE SCENE-----------------------
/* To actually be able to display anything with Three.js, we need three things:
1. A Scene
2. A Camera
3. A Renderer so we can render the scene with the camera
*/
var main=function() {
var CANVAS=document.getElementById("your_canvas");
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera (75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer({
antialias : true,
canvas : CANVAS
});
renderer.setSize(window.innerWidth, window.innerHeight);
//document.body.appendChild(renderer.domElement); //we add the renderer element to our HTML document
var geometry = new THREE.BoxGeometry (2,1,1);
var material = new THREE.MeshBasicMaterial ({color: 0x00ffff});
var cube = new THREE.Mesh (geometry, material);
scene.add(cube);
camera.position.z = 5;
//-------------RENDERING THE SCENE------------------------
function render(){
requestAnimationFrame(render);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
render();
};
In the header of default.ctp, I call script's library like that
<head>
<script type="text/javascript" src="/js/webgl_test.js"></script>
<script type="text/javascript" src="/js/three.min.js"></script>
</head>
Last step, I write some lines to show <canvas> element as below:
<div>
<ul>
<li onload='main()'>
<canvas id='your_canvas'style='position: absolute;'></canvas>
</li>
</ul>
</div>
Then, It show nothing :((
I'm using Google Maps for AngularJS to add a map to my project in AngularJS. Everything works great, except the case when at certain point I want the map center to be the exactly the same position as the clicked marker. So, on a click event I set the center of the map in AngularJS controller. Everything is OK, but when I drag or zoom the map, the marker position becomes the "new" center of the map. Does anybody know why is this happening? It's like the marker coords are binded in bi-directional way... Any help is appreciated! Thanks in advance
Here's the code:
// angular js controller
// map init [displays markers for all railway terminals in DB]
$scope.map = {
center: {
latitude: 48.22476,
longitude: 16.41356
},
zoom: 4
};
$scope.markers = []; // later filled with data from DB
// some code in between ...
// selection in table with termnals
$scope.selectTerminal = function (terminal) {
$scope.selected.terminal = terminal;
if (terminal.placeId != $scope.currentSelectedId) {
$scope.currentSelectedId = $scope.selected.terminal.placeId;
$scope.getTerminalDetails($scope.selected.terminal.placeId);
$scope.map.center = terminal.address.coords; // THIS LINE GIVES ME TROUBLE
$scope.map.zoom = 12;
}
};
So, the map center is set according to the coordinates of the selected terminal on select action (it is the new center of the map), and the zoom level increases. The thing is when i try to reset the map, or try to zoom or drag the map, the marker coordinates get the new map center coords, but it shouldn't. That's why I say 'two-way binding', I just can't figure this thing out.
Using your example you can do this.
$scope.map = {
center: {
latitude: 48.22476,
longitude: 16.41356
},
zoom: 4,
markersEvents: {
click: function(marker, eventName, terminal) {
$scope.map.center.latitude = terminal.coords.latitude;
$scope.map.center.longitude = terminal.coords.longitude;
}
}
};
remember in the html marker introduce events="map.markersEvents"
I have spent two days puzzling this and failed. Any assistance will be greatly appreciated.
I need a map centered on -18.975750, 32.669184 in a canvas of 1500px x 900px. I then to need to overlay coverage PNGs (obtained form www.heywhatsthat.com) with set code- transparency.
I have eventually arrived at the following code and it fails. I would like to add more than one PNG bound by it's co-ords, but cant even get one to work.
<script src="http://maps.google.com/maps?file=api&v=3&key=AIzaSyAGbZjXr2wr7dT2P3O5pNo5wvVF3JiaopU&sensor=false"
type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
if (GBrowserIsCompatible()) {
var map = new google.maps.MAP(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(-18.975750, 32.669184), 13);
map.setUIToDefault();
var imageBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-19.000417,30.999583),
new google.maps.LatLng(-17.999583,32.000417));
var oldmap = new google.maps.GroundOverlay(
"http://www.earthstation.mobi/cloakpS19E031.png",imageBounds);
oldmap.setMap(map);
}
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width: 1500px; height: 900px"></div>
</body>
</html>
What am I mssing and please point me in the right direction add multiple png overlays with transparency in the options.
Thanks
Brian
Zimbabwe
You have a lot of issues with your code. It looks like you're trying to migrate from V2 to V3, and you still have V2 methods and objects in your code. You're also not loading the JS APi correctly when you call in the of your HTML.
Here is functional code that displays the overlay using the V3 API, but it looks like the original center coordinates that you used do not place the map at the center of the overlay (you'll need to figure that out yourself). I've added comments where relevant so that you can see where you went astray. Note the call to the API library in the first script tag.
<script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyAGbZjXr2wr7dT2P3O5pNo5wvVF3JiaopU&sensor=false"
type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
//You don't need to use GBrowserIsCompatible, it's only for V2 of the API
//if (GBrowserIsCompatible()) {
//You need to set up options for the map that you reference when you
//instantiate the map object
var myOptions = {
center: new google.maps.LatLng(-18.975750, 32.669184),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//Your code references google.maps.MAP; it's google.maps.Map
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var imageBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-19.000417,30.999583),
new google.maps.LatLng(-17.999583,32.000417));
var oldmap = new google.maps.GroundOverlay(
"http://www.earthstation.mobi/cloakpS19E031.png",imageBounds);
oldmap.setMap(map);
//} <--Your code was missing this closing bracket for the conditional
//But the conditional is not even needed, since GBrowserCompatible is a V2 thing
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width: 1500px; height: 900px"></div>
</body>
</html>