原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。


文章目录

  • 前言
  • 一、django+admin
  • 二、geodjango+admin
  • 三、报错处理

前言

在前面的博客中,我们已经介绍了Geodjango的环境搭建和数据库操作,django本身提供了amdin后台,其实geodjango也有后台页面,现在我们来试着使用admin显示地图并加载空间字段。


一、django+admin

首先我们应该对django使用admin后台有一定基础,可以简单实现后台增删改查数据。

models.py文件如下

from django.contrib.gis.db import models
from django.utils import timezoneclass SarPic(models.Model):...ImageGeoJSON = models.PolygonField('成像地理信息', null=True, help_text='Metadata:ImageGeoJSON')...class Meta:verbose_name = '数据'verbose_name_plural = verbose_name

admin.py文件如下

from django.contrib import admin
from sarimage.models import SarPicclass SarPicAdmin(admin.ModelAdmin):list_display = ['ProductID',  'create_time', 'alter_time']list_per_page = 50list_filter = ['ImagingTime', 'SatellitePlatform', 'missionDataTakeId', 'SensorMode']# search_fields = ['ProductID', 'ImagingTime', 'SatelliteName', 'missionDataTakeId']fieldsets = (('影像图像', {'fields': ('ImageGeoJSON',)}))admin.site.register(SarPic, SarPicAdmin)

二、geodjango+admin

这里的变化为admin.ModelAdmin改为GeoModelAdmin(基于OpenLayers),除此之外还可以改成OSMGeoAdmin(基于OpenStreetMap)或LeafletGeoAdmin(基于Leaflet框架的第三方库django-leaflet)。

admin.py文件如下

from django.contrib import admin
from django.contrib.gis.admin import GeoModelAdmin
from sarimage.models import SarPicclass SarPicAdmin(GeoModelAdmin):list_display = ['ProductID',  'create_time', 'alter_time']list_per_page = 50list_filter = ['ImagingTime', 'SatellitePlatform', 'missionDataTakeId', 'SensorMode']# search_fields = ['ProductID', 'ImagingTime', 'SatelliteName', 'missionDataTakeId']fieldsets = (('影像图像', {'fields': ('ImageGeoJSON',)}))default_lon  # 默认的中心经度。default_lat  # 默认的中心纬度。default_zoom  # 要使用的默认缩放级别。默认值为4。extra_js  # 要包含的任何额外javascript的URL序列。map_template  # 重写用于生成javascript Slippy映射的模板。默认是 'gis/admin/openlayers.html' .map_width  # 地图的宽度,以像素为单位。默认值为600。map_height  # 地图的高度,以像素为单位。默认为400。openlayers_url  # 链接到Openlayers JavaScript的URL。默认为 'https://cdnjs.cloudflare.com/ajax/libs/openlayers/2.13.1/OpenLayers.js' .modifiable = False  # 禁用管理中现有几何图形字段的编辑admin.site.register(SarPic, SarPicAdmin)

三、报错处理

按照第二部分设置后,会报错 django.template.exceptions.TemplateDoesNotExist: gis/admin/openlayers.html。
我不知道其他人遇到怎么处理的,网络上也没找相关方案。主要原因是django的版本不同,django库的文件存在差异,部分版本缺少geodjango的template文件夹,这个需要我们自己补全。
templates必须放入我们项目的app中,我的项目app是sarimage,models.py是空间数据的类。

from django.contrib.gis.admin import GeoModelAdmin

我使用的是geodjango默认的GeoModelAdmin,所以我需要的是openlayers.html和openlayers.js文件。

openlayers.html文件内容如下

{% block extrastyle %}
{% load i18n static %}{% get_current_language_bidi as LANGUAGE_BIDI %}
<style type="text/css">#{{ id }}_map { width: {{ map_width }}px; height: {{ map_height }}px; }#{{ id }}_map .aligned label { float:inherit; }#{{ id }}_admin_map { position: relative; vertical-align: top; z-index: 0; float: {{ LANGUAGE_BIDI|yesno:"right,left" }}; }{% if not display_wkt %}#{{ id }} { display: none; }{% endif %}.olControlEditingToolbar .olControlModifyFeatureItemActive {background-image: url("{% static "admin/img/gis/move_vertex_on.svg" %}");background-repeat: no-repeat;}.olControlEditingToolbar .olControlModifyFeatureItemInactive {background-image: url("{% static "admin/img/gis/move_vertex_off.svg" %}");background-repeat: no-repeat;}
</style>
{% endblock %}
<span id="{{ id }}_admin_map">
<script>
//<![CDATA[
{% block openlayers %}{% include "gis/admin/openlayers.js" %}{% endblock %}
//]]>
</script>
<div id="{{ id }}_map" dir="{{ LANGUAGE_BIDI|yesno:'rtl,ltr,auto' }}"></div>
{% if editable %}
<a href="javascript:{{ module }}.clearFeatures()">{% translate "Delete all Features" %}</a>
{% endif %}
{% if display_wkt %}<p>{% translate "WKT debugging window:" %} </p>{% endif %}
<textarea id="{{ id }}" class="vWKTField required" cols="150" rows="10" name="{{ name }}">{{ wkt }}</textarea>
<script>{% block init_function %}{{ module }}.init();{% endblock %}</script>
</span>

openlayers.js文件内容如下

{% load l10n %}
OpenLayers.Projection.addTransform("EPSG:4326", "EPSG:3857", OpenLayers.Layer.SphericalMercator.projectForward);
{% block vars %}var {{ module }} = {};
{{ module }}.map = null; {{ module }}.controls = null; {{ module }}.panel = null; {{ module }}.re = new RegExp("^SRID=\\d+;(.+)", "i"); {{ module }}.layers = {};
{{ module }}.modifiable = {{ modifiable|yesno:"true,false" }};
{{ module }}.wkt_f = new OpenLayers.Format.WKT();
{{ module }}.is_collection = {{ is_collection|yesno:"true,false" }};
{{ module }}.collection_type = '{{ collection_type }}';
{{ module }}.is_generic = {{ is_generic|yesno:"true,false" }};
{{ module }}.is_linestring = {{ is_linestring|yesno:"true,false" }};
{{ module }}.is_polygon = {{ is_polygon|yesno:"true,false" }};
{{ module }}.is_point = {{ is_point|yesno:"true,false" }};
{% endblock %}
{{ module }}.get_ewkt = function(feat){return 'SRID={{ srid|unlocalize }};' + {{ module }}.wkt_f.write(feat);
};
{{ module }}.read_wkt = function(wkt){// OpenLayers cannot handle EWKT -- we make sure to strip it out.// EWKT is only exposed to OL if there's a validation error in the admin.var match = {{ module }}.re.exec(wkt);if (match){wkt = match[1];}return {{ module }}.wkt_f.read(wkt);
};
{{ module }}.write_wkt = function(feat){if ({{ module }}.is_collection){ {{ module }}.num_geom = feat.geometry.components.length;}else { {{ module }}.num_geom = 1;}document.getElementById('{{ id }}').value = {{ module }}.get_ewkt(feat);
};
{{ module }}.add_wkt = function(event){// This function will sync the contents of the `vector` layer with the// WKT in the text field.if ({{ module }}.is_collection){var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());for (var i = 0; i < {{ module }}.layers.vector.features.length; i++){feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]);}{{ module }}.write_wkt(feat);} else {// Make sure to remove any previously added features.if ({{ module }}.layers.vector.features.length > 1){old_feats = [{{ module }}.layers.vector.features[0]];{{ module }}.layers.vector.removeFeatures(old_feats);{{ module }}.layers.vector.destroyFeatures(old_feats);}{{ module }}.write_wkt(event.feature);}
};
{{ module }}.modify_wkt = function(event){if ({{ module }}.is_collection){if ({{ module }}.is_point){{{ module }}.add_wkt(event);return;} else {// When modifying the selected components are added to the// vector layer so we only increment to the `num_geom` value.var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());for (var i = 0; i < {{ module }}.num_geom; i++){feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]);}{{ module }}.write_wkt(feat);}} else {{{ module }}.write_wkt(event.feature);}
};
// Function to clear vector features and purge wkt from div
{{ module }}.deleteFeatures = function(){{{ module }}.layers.vector.removeFeatures({{ module }}.layers.vector.features);{{ module }}.layers.vector.destroyFeatures();
};
{{ module }}.clearFeatures = function (){{{ module }}.deleteFeatures();document.getElementById('{{ id }}').value = '';{% localize off %}{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});{% endlocalize %}
};
// Add Select control
{{ module }}.addSelectControl = function(){var select = new OpenLayers.Control.SelectFeature({{ module }}.layers.vector, {'toggle' : true, 'clickout' : true});{{ module }}.map.addControl(select);select.activate();
};
{{ module }}.enableDrawing = function(){{{ module }}.map.getControlsByClass('OpenLayers.Control.DrawFeature')[0].activate();
};
{{ module }}.enableEditing = function(){{{ module }}.map.getControlsByClass('OpenLayers.Control.ModifyFeature')[0].activate();
};
// Create an array of controls based on geometry type
{{ module }}.getControls = function(lyr){{{ module }}.panel = new OpenLayers.Control.Panel({'displayClass': 'olControlEditingToolbar'});{{ module }}.controls = [new OpenLayers.Control.Navigation()];if (!{{ module }}.modifiable && lyr.features.length) return;if ({{ module }}.is_linestring || {{ module }}.is_generic){{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}));}if ({{ module }}.is_polygon || {{ module }}.is_generic){{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}));}if ({{ module }}.is_point || {{ module }}.is_generic){{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}));}if ({{ module }}.modifiable){{{ module }}.controls.push(new OpenLayers.Control.ModifyFeature(lyr, {'displayClass': 'olControlModifyFeature'}));}
};
{{ module }}.init = function(){{% block map_options %}// The options hash, w/ zoom, resolution, and projection settings.var options = {
{% autoescape off %}{% for item in map_options.items %}      '{{ item.0 }}' : {{ item.1 }}{% if not forloop.last %},{% endif %}
{% endfor %}{% endautoescape %}    };{% endblock %}// The admin map for this geometry field.{% block map_creation %}{{ module }}.map = new OpenLayers.Map('{{ id }}_map', options);// Base Layer{{ module }}.layers.base = {% block base_layer %}new OpenLayers.Layer.WMS("{{ wms_name }}", "{{ wms_url }}", {layers: '{{ wms_layer }}'{{ wms_options|safe }}});{% endblock %}{{ module }}.map.addLayer({{ module }}.layers.base);{% endblock %}{% block extra_layers %}{% endblock %}{% if is_linestring %}OpenLayers.Feature.Vector.style["default"]["strokeWidth"] = 3; // Default too thin for linestrings. {% endif %}{{ module }}.layers.vector = new OpenLayers.Layer.Vector(" {{ field_name }}");{{ module }}.map.addLayer({{ module }}.layers.vector);// Read WKT from the text field.var wkt = document.getElementById('{{ id }}').value;if (wkt){// After reading into geometry, immediately write back to// WKT <textarea> as EWKT (so that SRID is included).var admin_geom = {{ module }}.read_wkt(wkt);{{ module }}.write_wkt(admin_geom);if ({{ module }}.is_collection){// If geometry collection, add each component individually so they may be// edited individually.for (var i = 0; i < {{ module }}.num_geom; i++){{{ module }}.layers.vector.addFeatures([new OpenLayers.Feature.Vector(admin_geom.geometry.components[i].clone())]);}} else {{{ module }}.layers.vector.addFeatures([admin_geom]);}// Zooming to the bounds.{{ module }}.map.zoomToExtent(admin_geom.geometry.getBounds());if ({{ module }}.is_point){{{ module }}.map.zoomTo({{ point_zoom }});}} else {{% localize off %}{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});{% endlocalize %}}// This allows editing of the geographic fields -- the modified WKT is// written back to the content field (as EWKT, so that the ORM will know// to transform back to original SRID).{{ module }}.layers.vector.events.on({"featuremodified" : {{ module }}.modify_wkt});{{ module }}.layers.vector.events.on({"featureadded" : {{ module }}.add_wkt});{% block controls %}// Map controls:// Add geometry specific panel of toolbar controls{{ module }}.getControls({{ module }}.layers.vector);{{ module }}.panel.addControls({{ module }}.controls);{{ module }}.map.addControl({{ module }}.panel);{{ module }}.addSelectControl();// Then add optional visual controls{% if mouse_position %}{{ module }}.map.addControl(new OpenLayers.Control.MousePosition());{% endif %}{% if scale_text %}{{ module }}.map.addControl(new OpenLayers.Control.Scale());{% endif %}{% if layerswitcher %}{{ module }}.map.addControl(new OpenLayers.Control.LayerSwitcher());{% endif %}// Then add optional behavior controls{% if not scrollable %}{{ module }}.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();{% endif %}{% endblock %}if (wkt){if ({{ module }}.modifiable){{{ module }}.enableEditing();}} else {{{ module }}.enableDrawing();}
};

【Admin后台管理】Geodjango后台显示地图并加载空间字段相关推荐

  1. 【WebGIS】二、基于Openlayers实现地图的加载与显示

    二.基于Openlayers实现地图的加载与显示 基于上文中配置好的环境,先通过Element Plus实现一个页面的布局,然后基于openlayers加载显示全球瓦片地图. 1. 引入element ...

  2. 百度地图调用加载显示Marker,并添加点击事件

    百度地图调用加载显示Marker,并添加点击事件 注册百度开发者账号,申请应用AK 百度地图开发平台官网 点击右上角控制台,选择创建应用 创建应用,勾选浏览器端,白名单填写* 注:如上线更改为公网IP ...

  3. 如何解决地图已加载却不能渲染的问题?

    Stack Overflow问题分享 Stack Overflow上有一个海外开发者提问:我在我的项目中使用华为Map Kit,地图已加载但未渲染? 解决方案 一般来说引起地图加载未渲染可能的原因有很 ...

  4. swift 百度地图加载与百度地图电子围栏加载

    最近在写百度地图电子围栏加载,研究源码,也花了一些时间. 1.百度电子围栏整体思路 1)用户创造实体,赋予监控权限 2)对该实体创造电子围栏,有服务端和本地端两种方式,先创造实体,上传到的服务器中.在 ...

  5. OpenLayers学习笔记中级篇(一、各种地图的加载)

    学习了前面的初级篇,相信大家对OplenLayers已经有了一个初步的认识,下面我们再继续深入学习OpenLayers的相关功能! 我们这节主要是加载各种各样的地图,包括在线服务的地图,比如天地图.高 ...

  6. 【笔记】unity大地图分块加载

    1.大地图分块加载     chunk的大小可动态调整     写工具做地块拆分         如果地块是由1个个小格子单元组成的,则可按位置进行划分保存成多个chunk预设         如果地 ...

  7. WebGIS实战:Vue+Openlayers实现网络地图的加载与切换

    目录 前言 1.效果图 2.实现步骤 3.下一步计划 相关Web GIS实战信息: 上一篇博客:WebGIS实战:Web GIS开发环境配置 下一篇博客:WebGIS实战:Vue+Openlayers ...

  8. ios 高德地图加载瓦片地图_IOS 高德地图 API 加载 WMS 服务

    IOS 高德地图 API 加载 WMS 服务 本文主要介绍通过自定义高德地图 MATileOverlay 接口,添加 WMS 服务到地图上.废话少说,先贴代码. 代码 自定义类 WMSTileOver ...

  9. OGC标准WMTS服务概念与地图商的瓦片编号流派-web地图切片加载

    还不知道地图栅格化切片等相关GIS原理的,推荐阅读<webGIS底图栅格化与实时数据合成处理原理,地图API设计,xyz加载> OGC概念 OGC全称--开放地理空间信息联盟(Open G ...

最新文章

  1. 深入理解阿里分布式消息中间件
  2. Java 面试知识点解析(六)——数据库篇
  3. 程序员过关斩将--论商品促销代码的优雅性
  4. pytorch元素相乘_bert_pytorch学习(1)
  5. 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器
  6. CentOS卸载自带的JDK
  7. RoomIt屏幕画笔工具
  8. 基于单片机at89s52的频率计设计c语言程序,基于AT89S52单片机电子万年历设计(附程序,电路原理图)...
  9. 微软新的邮件帐户域名 @live.com和@windowslive.com
  10. 程序员面试、算法研究、编程艺术、红黑树、机器学习5大系列集锦(转)
  11. POJ2126 多项式分解定理
  12. 互联网技术架构——画龙点睛
  13. 解决 “git status”失败,错误代码 1:BUG(fork bomb):D:\Git\bin\git.exe·····
  14. docker 实践(十一)docker swarm
  15. 计算机系统基础第四篇-6 elf文件的链接
  16. MDK470A LIC/ERROR R206: NO REGISTRY ACCESS, ADMINISTRATION RIGHTS REQUIRED
  17. 3D Master让您的业务精益求精
  18. 构建 ERC20 代币合约
  19. 百度 冷色008 博客园 企业微信
  20. 经典sql,高级sql

热门文章

  1. 看似生意冷清的烟酒店靠什么赚钱,有哪些你不知道的隐形收入
  2. sql.gz还原mysql_mysql 数据备份还原
  3. 按钮点击涟漪效果,基于vue
  4. 百度、腾讯、阿里巴巴的真正大老板是谁
  5. 深入SpringBoot源码(四)初识Environment
  6. 预讲会讲者招募 | 招募 NeurlPS 2022 一作华人讲者啦!!!
  7. 第一章—图像处理基础
  8. 一文带你了解 Google I/O 2022 精彩汇总与个人感想
  9. 使用 HandlerThread
  10. OutputCache祥解