I'm trying to place markers based on the latitude and longitude stored in a model on a Google Map using the API and HTML5 geolocation.
The issue is how to loop through the lat/lon info for each object stored within JavaScript tags using template keywords, which I don't believe can be done in Django.
I found a similar question here Adding Google Map Markers with DJango Template Tags in Javascript which I mildly modified and placed within a template – not a separate script file – but it doesn't seem to work:
function loadMarkers(){
{% for story in stories %}
var point = new google.maps.LatLng({{story.latitude}},{{story.longitude}});
var marker = new google.maps.Marker({
position: point,
map: map
});
{% endfor %}
}
Any insight on how to properly loop through items in a stored Django object with lat, lon info and place these on a Google Map using the API would be very appreciated.
I use django-geoposition to manage my geodata
from django.db import models
from geoposition.fields import GeopositionField
class Zone(models.Model):
name = models.CharField(max_length = 50 )
kuerzel = models.CharField(max_length = 3 )
kn_nr = models.CharField(max_length = 5 )
beschreibung = models.CharField(max_length = 300 )
adresse = models.CharField(max_length = 100 )
position = GeopositionField()
view.py
from geo.models import Zone
from django.shortcuts import render_to_response, get_object_or_404, redirect
def ShowZonen(request):
zone=Zone.objects.all()
return render_to_response('zonen.html', {"zone": zone})
def showZoneDetail(request, zone_id):
zone=Zone.objects.get(id=zone_id)
return render_to_response('zonendetail.html', {"zone": zone})
template
zonendetail.html
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var map;
function initialize() {
var mapDiv = document.getElementById('map-canvas');
map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(48.208174,16.373819),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListenerOnce(map, 'tilesloaded', addMarkers);
}
function addMarkers() {
{% for mark in zone %}
var point = new google.maps.LatLng({{mark.position.latitude}},{{mark.position.longitude}});
var image = '{{ STATIC_PREFIX }}'+ 'checkmark.png';
var marker = new google.maps.Marker({
position: point,
map: map,
icon: image,
url: 'http://172.16.0.101:8882/zone/' + {{mark.id}},
title: '{{ mark.id }}',
});
marker['infowindow'] = new google.maps.InfoWindow({
content: "<h1>{{mark.name}}</h1> <br> {{ mark.name }} <p> {{ mark.name }}",
});
google.maps.event.addListener(marker, 'click', function() {
//window.location.href = this.url;
this['infowindow'].open(map, this);
});
google.maps.event.addListener(marker, 'mouseover', function() {
// this['infowindow'].open(map, this);
});
google.maps.event.addListener(marker, 'mouseout', function() {
// this['infowindow'].close(map, this);
});
{% endfor %}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Related
Potion of my html code do do style
<script type="text/javascript">
function our_Layers (map, options){
var datasets = new L.GeoJSON.AJAX("{% url 'owner' %}",{
style: function colors(feature){
switch(feature.properties.lr){
case "{{LR}}":
return{
color: 'red'
};
break
}
},
onEachFeature: function(feature, layer){
//layer.bindPopup(feature.properties.lr.toString());
layer.bindPopup('<strong>LR No.: </strong>'+ feature.properties.lr.toString()
);
}
});
datasets.addTo(map);
}
</script>
{% leaflet_map "parcels" callback="window.our_Layers" %}
my view in django
def Usermap(request):
plots1 = request.user.person.Persona.all()
for Registration in plots1:
LR=(Registration.parcels.lr)
context = {'plots':plots1,'LR':LR}
return render(request, 'Cadastre/Usermap.html', context)
Have used that for loop in django to show me available lr which are 3 but i cant use django for loop tags inside the leaflet function any help
I found a way to go around it..first i perform a for loop in django views and append my result in a list.
example
def Usermap(request):
plots1 = request.user.person.Persona.all()
LR =[]
for Registration in plots1:
LR.append(Registration.parcels.lr)
context = {'plots':plots1,'LR':LR}
return render(request, 'Cadastre/Usermap.html', context)
then do another loop in html to access the list items and use it to style my map dynamically.
example
<script type="text/javascript">
datasets = new L.GeoJSON.AJAX("{% url 'Plots' %}",{
style: function colors(feature){
var LRS = {{LR|safe}};
var x;
for (x of LRS){
switch(feature.properties.lr){
case x:
return{
color: 'red'
};
break
}
}
},
onEachFeature: onEachFeature
}).addTo(map);
</script>
I hope this help someone with same issue since there is no other answer thank you.
I have a model class name Restaurant with Latitude and Longitude and inserted many data already in this class and by these fields, I wanna show multiple markers of google map.
# restaurant.html
<div id="map"></div>
{% for i in restaurents %}
<script>
var locations = [
[{{ i.restaurant }}, {{ i.latitude }}, {{ i.longitude }}, {{ i.id }}]
];
{#var locations = [#}
{# ['Bondi Beach', -33.890542, 151.274856, 4],#}
{# ['Coogee Beach', -33.923036, 151.259052, 5],#}
{# ['Cronulla Beach', -34.028249, 151.157507, 3],#}
{# ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],#}
{# ['Maroubra Beach', -33.950198, 151.259302, 1]#}
{#];#}
// When the user clicks the marker, an info window opens.
function initMap() {
var myLatLng = {lat: -33.90, lng: 151.16};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: myLatLng
});
var count=0;
for (count = 0; count < locations.length; count++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map
});
marker.info = new google.maps.InfoWindow({
content: locations [count][0]
});
google.maps.event.addListener(marker, 'click', function() {
// this = marker
var marker_map = this.getMap();
this.info.open(marker_map, this);
// Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});
}
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBqEz7ozYxKa53JAeN4GFN2HfilyiFCbvw&callback=initMap">
</script>
{% endfor %}
Initially, I have defined some data and it's working good that has commented out in this code. But when I retrieved data via looping from my database then map doesn't work.
I don't understand from where and how I can access this data.
access
var locations = [
[{{ i.restaurant }}, {{ i.latitude }}, {{ i.longitude }}, {{ i.id }}]
];
many time I searched and also got some answer but doesn't work properly.
Thanks for Advance.
{% for i in restaurents %}
<div id="map" style="padding-bottom: 140px; padding-top: 140px"></div>
<script>
function initMap() {
var locations = [];
locations.push({name: {{ i.restaurant }}, latlng: new google.maps.LatLng( {{ i.latitude }}, {{ i.longitude }}) });
locations.push({name: 'Bondi Beach', latlng: new google.maps.LatLng( -33.890542, 151.274856) });
locations.push({name: 'Coogee Beach', latlng: new google.maps.LatLng( -33.923036, 151.259052) });
var uluru = { lat: {{ i.latitude }}, lng: {{ i.longitude }} };
var map = new google.maps.Map(
document.getElementById('map'), {zoom: 8, center: uluru});
for(var j=0; j<locations.length; j++){
var marker = new google.maps.Marker({
position: new google.maps.LatLng({position: locations[j].latlng, map: map, title: locations[j].name}),
});
bounds.extend(locations[j].latlng);
}
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBqEz7ozYxKa53JAeN4GFN2HfilyiFCbvw&callback=initMap">
</script>
{% endfor %}
Several kinds of steps already I've followed. For example the above code. When I'm gonna access that data then don't work but if I initially define those data it's working fine.
I'm using OpenLayers to create, display and edit features on the map. Features are saved as a JSONField in Django. Post Save I add a key django_pk to the JSON. How can I get this djanog_pk directly from the feature?
I need to do this so when the feature is edited, I know what feature to update in Django.
My JS code below:
<script>
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var source = new ol.source.Vector({wrapX: false});
var vector = new ol.layer.Vector({
source: source
});
var format = new ol.format.GeoJSON();
var select = new ol.interaction.Select({
wrapX: false
});
var modify = new ol.interaction.Modify({
features: select.getFeatures()
});
var map = new ol.Map({
interactions: ol.interaction.defaults().extend([select, modify]),
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [-11000000, 4600000],
zoom: 4
})
});
var features = new ol.source.Vector({
projection: 'EPSG:4326'
});
{% for polygon in polygons.0.gates %}
console.log(format.readFeature({{ polygon|safe }}).getProperties()))
{% endfor %}
features.addFeature(format.readFeature({{ polygons.0.protected_area|safe }}));
{% for polygon in polygons.0.gates %}
features.addFeature(format.readFeature({{ polygon|safe }}));
console.log(format.readFeature({{ polygon|safe }}))
{% endfor %}
var featureOverlay = new ol.layer.Vector({
source: features,
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({
color: '#ff78d1',
width: 2
}),
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: '#4ca6b6'
}),
})
})
});
featureOverlay.setMap(map);
</script>
I tried this: Buyt it only return geometry:
select.on('select', function(e) {
console.log(e.selected[0].getProperties())
});
The JSONField in Django looks like this:
{
"geometry":{
"type":"Polygon",
"coordinates":[
[
[
-11156543.033928039,
6698655.0485978
],
[
-11410925.464061106,
5896371.999716589
],
[
-9972686.33984723,
5084305.011214877
],
[
-9512841.177683609,
6649735.350495286
],
[
-10090093.61529326,
6972605.357971871
],
[
-11156543.033928039,
6698655.0485978
]
]
]
},
"type":"Feature",
"properties":null,
"django_pk":10
}
So I need to find the django_pk for a feature when editing it, it selecting it, ot deleting it.
Not sure how to get this information
Ok, I its actually simple.
You can read any property of the GeoJSON format:
select.on('select', function(e) {
console.log(e.selected[0].getProperties())
});
Select being:
var select = new ol.interaction.Select({
wrapX: false
});
And in my Django code I just do this on post_save:
#receiver(post_save, sender=ProtectedArea)
def update_json(sender, instance, created, **kwargs):
post_save.disconnect(update_json, sender=ProtectedArea)
try:
instance.polygone = literal_eval("%s" % instance.geojson_file.read())
except:
pass
if instance.polygone['properties'] == None:
instance.polygone['properties'] = {}
instance.polygone['properties']['pk'] = instance.pk
else:
instance.polygone['properties']['pk'] = instance.pk
instance.save()
post_save.connect(update_json, sender=ProtectedArea)
I trying to create a Angularjs rating app with django. I'm using the rating mechanism from angular-bootstrap. http://angular-ui.github.io/bootstrap/
I've created a controller which can handle ratings for only one object but i would like to create an app witch can rate any object on my website no matter where they are.
To identify each object, I using:
data-id="{{ id }}" data-app-label="{{ app_label }}" data-model="{{ model }}"
My template:
<div ng-app="ratingApp">
<div ng-controller="RatingCtrl">
<div class="rating-input">
<div rating id="rating" ng-model="rate" max="max" readonly="isReadonly" on-leave="overStar = null" data-id="{{ id }}" data-app-label="{{ app_label }}" data-model="{{ model }}" ng-click="postRating(value)"></div>
<div class="menge thanks" ng-hide="showMessage"><span>{$ menge $}</span></div>
<div class="message"><div class="ng-hide thanks" ng-show="showMessage">{$ message $}</div></div>
</div>
</div>
</div>
My controller:
ratingControllers.controller('RatingCtrl', ['$scope', '$http', '$element', '$timeout',
function ($scope, $http, $element, $timeout) {
var messageTimer = false,
displayDuration = 2000;
$scope.message = "Thanks!";
$scope.showMessage = false;
$scope.doGreeting = function () {
if (messageTimer) {
$timeout.cancel(messageTimer);
}
$scope.showMessage = true;
messageTimer = $timeout(function () {
$scope.showMessage = false;
}, displayDuration);
};
$scope.max = 6;
$scope.isReadonly = false;
var id = $element.find("#rating").attr("data-id");
var app_label = $element.find("#rating").attr("data-app-label");
var model = $element.find("#rating").attr("data-model");
var request = $http.post("/rating/get-rating/", {id: id, app_label: app_label, model: model});
request.success(function (data) {
$scope.rate = data.sterne;
$scope.menge = data.menge;
});
$scope.postRating = function (value) {
var request = $http.post("/rating/set-rating/", {id: id, app_label: app_label, model: model, sterne: $scope.rate});
request.success(function (data) {
$scope.doGreeting();
if (data.message) {
alert(data.message);
}
});
};
}
]);
Any idea how can i make this more reusable to rate any object on the website?
I would like to be able to define the model for a component template inside the Ember.Component js instead of inside the route where the component is sitting. I have not seen any examples which are doing this...
Here I have my component template:
<script type="text/x-handlebars" id="components/info-box">
<div class="infoBox box">
<p>
<label>
{{preUnits}}
</label>
<span>
{{value}}
</span>
</p>
</div>
</script>
And here is how I am placing it inside one route template:
{{info-box title='Total Area' dataDef='buddhaData:DataGet/site/areaNum'}}
What I would like to do is use my relevant Ember.Component to do some stuff with the parameters of the info-box and then return a model for it.
App.InfoBoxComponent = Ember.Component.extend({
buildIt: function(){
var container = $('#' + this.get('elementId') );
var title = this.get('title');
var preUnits = this.get('preUnits') || '';
var dataDef = this.get('dataDef');
// Do stuff with dataDef.
var model = {
preUnits: '$',
value: 5000
}
// Hopefully return model somehow.
},
didInsertElement: function(){
this.buildIt();
}
});
I want to be able to use this component inside a bunch of different routes, and I do not want to have to refer to the route that a particular info-box is inside of in order to give the info-box its model, is this possible, or should I use some other feature, like a regular template and the render helper?
Once you have the model object, just set properties on the component itself:
App.InfoBoxComponent = Ember.Component.extend({
buildIt: function(){
var container = $('#' + this.get('elementId') );
var title = this.get('title');
var preUnits = this.get('preUnits') || '';
var dataDef = this.get('dataDef');
// Do stuff with dataDef.
var model = {
preUnits: '$',
value: 5000
}
// Set component's preUnits and value properties directly
this.setProperty('preUnits', model.preUnits);
this.setProperty('value', model.value);
// or
this.setProperties(model);
// Hopefully return model somehow.
},
didInsertElement: function(){
this.buildIt();
}
});
You should use render if you'd like to define which model you want to use (if the model is different than the current context). If it's the same context, you should just use partials. You could also generate helper and pass in the model to that.
Ember.Handlebars.helper('autocomplete', Ember.View.extend({
templateName: 'controls/autocomplete',
filteredList: function() {
var list = this.get('list'),
filter = this.get('filter');
if (!filter) { return list; }
return list.filter(function(item) {
return item.name.indexOf(filter) !== -1;
});
}.property('list.[]', 'filter')
}));
Usage:
<script type="text/x-handlebars" data-template-name="application">
{{autocomplete list=list1}}
{{autocomplete list=list2}}
</script>
<script type="text/x-handlebars" data-template-name="controls/autocomplete">
<p>{{input type="text" value=view.filter}}</p>
<ul>
{{#each view.filteredList}}
<li >{{name}}</li>
{{/each}}
</ul>
</script>
Full example