I have a winform client, that contains a webbrowser control inside it. Working with C# in visual studio, and running a MSSQL for persistance.
My goal is:
Take the data stored in my MSSQL (handle via DBML/DataContext), and show a marker on a google map (Javascript v3) for each address I got in the database.
Right now I have an HTML file in my app solution, with the JS code for showing a Google map like this (lets call it mymap.html):
var map;
var _geoLocationsArr = [
["Tranehavevej 10, 2450", "Fiberby"],
["Tranehavevej 8, 2450", "Fiberby"],
["Tranehavevej 6, 2450", "Fiberby"],
["Tranehavevej 4, 2450", "Fiberby"],
["Johan Kellers Vej 27, 2450", "Service"],
["Johan Kellers Vej 25, 2450", "Service"],
["Johan Kellers Vej 23, 2450", "Service"],
["Johan Kellers Vej 21, 2450", "Service"],
["Johan Kellers Vej 24, 2450", "Potentiel"]
];
var customIcons = {
Fiberby: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_red.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png',
title: 'Fiberby'
},
Service: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_yellow.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png',
title: 'Service'
},
Unknown: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_gray.png',
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png',
title: 'Ukendt'
}
};
var geocoder;
function initialize(lat, lng) {
geocoder = new google.maps.Geocoder();
var myLatlng = new google.maps.LatLng(lat, lng);
var mapOptions = {
zoom: 14,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
//geocodeMe();
}
function toggle() {
initialize(55.66718, 12.5411);
for (var i = 0; i < _locations.length; i++) {
var item = _locations[i];
var latlng = new google.maps.LatLng(item[0], item[1]);
var icon = customIcons[_locations[i][1]] || {};
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: icon.icon,
shadow: icon.shadow,
title: "Hello World! " + i
});
}
}
function toggleGeocodes() {
initialize(55.66718, 12.5411);
for (var i = 0; i < _geoLocationsArr.length; i++) {
geocodeMe(_geoLocationsArr[i][0], _geoLocationsArr[i][1]);
}
}
function geocodeMe(address, type) {
geocoder.geocode({
'address': address
},
function(result, status){
if(status == google.maps.GeocoderStatus.OK){
map.setCenter(result[0].geometry.location);
var icon = customIcons[type] || customIcons['Unknown'];
var marker = new google.maps.Marker({
map: map,
icon: icon.icon,
shadow: icon.shadow,
position: result[0].geometry.location,
title: icon.title
});
} else{
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
</script>
</head>
<body onload="initialize(55.665919, 12.55482)">
<div id="map_canvas" style="width: 100%; height: 100%"></div>
</body>
When I hit the "Geo toggle" button in my winforms, it shows the markers on the map for each geocoded address in _geoLocationsArr. And everything is working perfect.
But! Now, I want to replace the _geoLocationsArr with data generated from my winform, where my winform creates the marker data (xml, or string array, it doesn't really matter what format for me, what matters is that it can send data from the winform to the JS in the HTML page).
So, how can I create data within my WinForm, and when clicking the button calling the JS html page with the data the form has created as a parameter?
So when calling function toogleGeocodes() it will have the data as a parameter like function toggleGeocodes(_myGeoLocationsArr[]) where _myGeoLocationsArr[] is something that the winform has created and sended as parameter when calling the function.
Related
I'm currently on a ReactJS+Nodejs application, trying to integrate OpenLayers. What I need is to change the GPS position of a marker, in real-time (via socket.io).
So far, I've come up with this code:
this.map = new Map({
target: "map",
layers: [
new TileLayer({
source: new XYZ({
attributions: 'Tiles © ArcGIS',
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'
})
}),
],
view: new View({
center: fromLonLat([-8.455826, 40.168307]),
rotation: 1.1344640138,
easing: 0.5
})
});
var vectorSource = new VectorSource({});
var markersLayer = new VectorLayer({
source: vectorSource,
});
this.map.addLayer(markersLayer);
var point1 = new Point(
fromLonLat([-8.455826, 40.168307])
);
var point2 = new Point(
fromLonLat([-8.456819, 40.166388])
);
var marker = new Feature({
geometry: point1,
name: "My point",
});
vectorSource.addFeature(marker);
var style = new Style({
image: new CircleStyle({
radius: 7,
fill: new Fill({color: 'black'}),
stroke: new Stroke({
color: 'white', width: 2
})
})
});
marker.setStyle(style);
setTimeout(function () {
marker.setGeometry(point2);
marker.getGeometry().translate(40, -40);
}, 3500);
The marker moves, however the transition occurs in an instant. Is there a way to make it move like a "CSS linear transition" to give it a more realistic look?
Using a timer you could split the move into steps along the line between the old and new positions, e.g. for 100 10ms steps
var line = new LineString([oldCoordinates, newCoordinates])];
var step = 0;
var key = setInterval( function() {
if (step < 100) {
step++;
marker.setGeometry(new Point(line.getCoordinateAt(step/100)));
} else {
clearInterval(key);
}
}, 10);
You might also be able to base something on the flight animation example https://openlayers.org/en/latest/examples/flight-animation.html
In my app using google place map predefined location but i need location name lat and lng from google map dynamically when moves the marker on google
Im using angularJs 1.5
my code like this
$scope.Markers =
{
"lat": '12.976154',
"lng": '77.445760',
}
//Setting the Map options.
$scope.MapOptions = {
center: new google.maps.LatLng($scope.Markers.lat, $scope.Markers.lng),
zoom: 7,
rotation: 45,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//Initializing the InfoWindow, Map and LatLngBounds objects.
$scope.InfoWindow = new google.maps.InfoWindow();
$scope.Latlngbounds = new google.maps.LatLngBounds();
$scope.Map = new google.maps.Map(document.getElementById("dvMap"), $scope.MapOptions);
//Looping through the Array and adding Markers.
// for (var i = 0; i < $scope.Markers.length; i++) {
// var data = $scope.Markers[i];
var myLatlng = new google.maps.LatLng($scope.Markers.lat, $scope.Markers.lng);
//Initializing the Marker object.
var marker = new google.maps.Marker({
position: myLatlng,
map: $scope.Map,
title: $scope.Markers.title
});
//Adding InfoWindow to the Marker.
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
// $scope.InfoWindow.setContent("<div style = 'width:100px;min-height:40px'>" + data.description + "</div>");
// $scope.InfoWindow.open($scope.Map, marker);
});
})(marker, $scope.Markers);
//Plotting the Marker on the Map.
$scope.Latlngbounds.extend(marker.position);
// }
//Adjusting the Map for best display.
$scope.Map.setCenter($scope.Latlngbounds.getCenter());
$scope.Map.fitBounds ($scope.Latlngbounds);
Please help me
You can attach the drag & dragend events to the google maps markers using 'google.maps.event.addListener' method.
function getMarkerCoords(markerobj){
google.maps.event.addListener(markerobj, 'dragend', function(evt){
infoWindow.setOptions({
content: '<p>Marker Current Lat: ' + evt.latLng.lat().toFixed(3) + ' Current Lng: ' + evt.latLng.lng().toFixed(3) + '</p>'
});
infoWindow.open(map, markerobj);
});
google.maps.event.addListener(markerobj, 'drag', function(evt){
console.log("marker is being dragged");
});
}
I'm developing an application in DevExtreme Mobile. In application, I use DXMap in this application. How can I use the marker clusterer structure in DevExtreme Mobile App?
You can use Google Maps Marker Clusterer API to create and manage per-zoom-level clusters for a large number of DevExtreme dxMap markers. Here is an example:
dxMap Marker Clusterer
This example is based on the approach described in the Google Too Many Markers! article
Here is sample code:
$("#dxMap").dxMap({
zoom: 3,
width: "100%",
height: 800,
onReady: function (s) {
var map = s.originalMap;
var markers = [];
for (var i = 0; i < 100; i++) {
var dataPhoto = data.photos[i];
var latLng = new google.maps.LatLng(dataPhoto.latitude, dataPhoto.longitude);
var marker = new google.maps.Marker({
position: latLng
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
}
});
The kry is to use the google maps api. I did it for my app, here how.
This the html, very simple:
<div data-options="dxView : { name: 'map', title: 'Punti vendita', pane: 'master', secure:true } ">
<div data-bind="dxCommand: { id: 'back', behavior: 'back', type: 'back', visible: false }"></div>
<div data-options="dxContent : { targetPlaceholder: 'content' } ">
<div style="width: 100%; height: 100%;">
<div data-bind="dxMap:options"></div> <!--this for the map-->
<div id="large-indicator" data-bind="dxLoadIndicator: {height: 60,width: 60}" style="display:inline;z-index:99;" />
<div data-bind="dxPopover: {
width: 200,
height: 'auto',
visible: visible,
}">
</div>
</div>
</div>
</div>
When the page loads, the app read the gps coordinates:
function handleViewShown() {
navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
jQuery("#large-indicator").css("display", "none"); //this is just a gif to indicate the user to wait the end of the operation
}
If the gps location is correctly read, I save the coordinates (the center of the map):
function onSuccess(position) {
var lat1 = position.coords.latitude;
var lon1 = position.coords.longitude;
center([lat1, lon1]);
}
And these are the options I set to my dxMap:
options: {
showControls: true,
key: { google: "myGoogleApiKey" },
center: center,
width: "100%",
height: "100%",
zoom: zoom,
provider: "google",
mapType: "satellite",
autoAdjust: false,
onReady: function (s) {
LoadPoints();
var map = s.originalMap;
var markers = [];
for (var i = 0; i < MyPoints().length; i++) {
var data = MyPoints()[i];
var latLng = new google.maps.LatLng(data.location[0], data.location[1]);
var marker = createMarker(latLng, data.title, map, data.idimp);
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers, { imagePath: 'images/m' });
}
},
Where MyPoints is populated calling LoadPoints:
function LoadPoints() {
$.ajax({
type: "POST",
async:false,
contentType: "application/json",
dataType: "json",
url: myApiUrl,
success: function (Response) {
var tempArray = [];
for (var point in Response) {
var location = [Response[p]["latitudine"], Response[p]["longitudine"]];
var title = Response[p]["name"] + " - " + Response[p]["city"];
var temp = { title: title, location: location, tooltip: title, onClick: GoToNavigator, idpoint: Response[p]["id"] };
tempArray.push(temp);
}
MyPoints(tempArray);
},
error: function (Response) {
jQuery("#large-indicator").css("display", "none");
var mex = Response["responseText"];
DevExpress.ui.notify(mex, "error");
}
});
}
Note that in the folder Myproject.Mobile/images I included the images m1.png, m2.png, m3.png, m4.png and m5.png.
You can found them here.
I'm trying to load an image on canvas using Backbone + KineticJS. However the image doesn't seem to appear.
First I load the images using a model. (I'm loading the image locally so its already available)
var KineticModel = Backbone.Model.extend({
myImg: null,
createImg : function() {
var imageObj = new Image();
var kinImg = new Kinetic.Image()
imageObj.onload = function() {
kinImg.setAttrs({
x: 10,
y: 10,
image: imageObj,
width: 578,
height: 400
})
}
imageObj.src = 'test/img/vader.png';
return kinImg;
}
});
Then create the View
var KineticView = Backbone.View.extend({
id: 'container',
stage: null,
layer: null,
initialize: function (options) {
model: options.model;
el: options.el;
this.layer = new Kinetic.Layer();
this.stage = new Kinetic.Stage({ container: this.el, width: 600, height: 600 });
this.stage.add(this.layer);
},
render: function () {
var myImg = this.model.createImg();
this.layer.add(myImg);
this.stage.add(this.layer);
this.stage.draw();
}
});
Finally to tie it all up
var KModel= new KineticModel({});
var imgcontainer = $('#container').get();
view = new KineticView({model:KModel, el:imgcontainer});
view.render();
The page loads without any errors, but no image.
Console logs show that the Image Models have been passed to the layers.
Any help will be greatly appreciated!
Redraw layer after setting attrs:
kinImg.setAttrs({
x: 10,
y: 10,
image: imageObj,
width: 578,
height: 400
});
yourLayer.draw();
Note: you are working with view (Kinetic object) inside Backbone.Model - this is bad approach. Model should works only with data. Move createImg function to View.
Also look at this plugin: https://github.com/slash-system/backbone.kineticview
;)
I'm a not so familiar with the Google Maps API yet but I was able to figure out most questions a beginners faults. ;) But what I don't get is to center the map between the two markers I set and to auto zoom it... ;(
Maybe someone has the right hint for me...
Thanks and cheers!
<script> function initialize() {
var myLatLng = new google.maps.LatLng(0, 0);
var mapOptions = {
zoom: 3,
mapTypeControl: false,
navigationControl: false,
scrollwheel: false,
streetViewControl: false,
zoomControl: false,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
var flightPlanCoordinates = [
new google.maps.LatLng(100, 100),
new google.maps.LatLng(120, 120)
];
var lineSymbol = {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
};
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 0.5,
icons: [{
icon: lineSymbol,
offset: '100%'
}],
strokeWeight: 2
});
flightPath.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);</script>
<div id="map" style="width: 100%; height: 300px"></div>
<script>jQuery('#myModal-<? the_ID(); ?>').on('shown', function () {
google.maps.event.trigger(map, 'resize');
map.setCenter(new google.maps.LatLng(42.3605336, -72.6362989));
})</script>
You need to fit the bounds of the map as it pertains to your markers.
// Make an array of the LatLng's of the markers you want to show
var LatLngList = new Array (new google.maps.LatLng (52.537,-2.061), new google.maps.LatLng (52.564,-2.017));
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds ();
// Go through each...
for (var i = 0, LtLgLen = LatLngList.length; i < LtLgLen; i++) {
// And increase the bounds to take this point
bounds.extend (LatLngList[i]);
}
// Fit these bounds to the map
map.fitBounds (bounds);
// Make an array of the LatLng's of the markers you want to show
var LatLngList = new Array (
new google.maps.LatLng(<?php echo esc_html( $et_location_lat ); ?>, <?php echo esc_html( $et_location_lng ); ?>),
new google.maps.LatLng(<?php echo esc_html( $destination_lat ); ?>, <?php echo esc_html( $destination_lng ); ?>)
);
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds ();
// Go through each...
for (var i = 0, LtLgLen = LatLngList.length; i < LtLgLen; i++) {
// And increase the bounds to take this point
bounds.extend (LatLngList[i]);
}
// Fit these bounds to the map
map.fitBounds (bounds);
As I open the map within a modal box I've to reload the bounced map as soon as I open it:
jQuery('#myModal-<? the_ID(); ?>').on('shown', function () {
google.maps.event.trigger(map, 'resize');
map.fitBounds (bounds);
})