def wdpapoly2mpa(): wpolys = WdpaPolygon.objects.all().defer(*WdpaPolygon.get_geom_fields()).order_by("wdpaid") count = 0 for wpoly in wpolys: mpa, created = Mpa.objects.get_or_create(wdpa_id=wpoly.wdpaid) count += 1 print count mpa.name = wpoly.name mpa.wdpa_id = wpoly.wdpaid mpa.country = wpoly.country mpa.sub_location = wpoly.sub_loc mpa.designation = wpoly.desig mpa.designation_eng = wpoly.desig_eng mpa.designation_type = wpoly.desig_type mpa.iucn_category = wpoly.iucn_cat mpa.int_criteria = wpoly.int_crit mpa.marine = wpoly.marine mpa.status = wpoly.status mpa.status_year = wpoly.status_yr mpa.area_notes = wpoly.area_notes mpa.rep_m_area = wpoly.rep_m_area mpa.calc_m_area = wpoly.gis_m_area mpa.rep_area = wpoly.rep_area mpa.calc_area = wpoly.gis_area mpa.gov_type = wpoly.gov_type mpa.mgmt_auth = wpoly.mang_auth mpa.mgmt_plan_ref = wpoly.mang_plan # mpa.geom_smerc = wpoly.geom_smerc # mpa.geom = wpoly.geom # mpa.geog = wpoly.geog mpa.save() # SQL update all geometry rows, much faster than through django print "UPDATE geometry columns" cursor = connection.cursor() cursor.execute("UPDATE mpa_mpa SET geog = w.geog FROM wdpa_wdpapolygon as w WHERE mpa_mpa.wdpa_id = w.wdpaid") transaction.commit_unless_managed() print "UPDATE complete" Mpa.set_all_geom_from_geog()
def lookup_point(request): """Find nearby polygons with a point and search radius. Three lookup methods are supported: sphericalmercator: radius (in km) is applied to search buffer in 900913 (aka Google Spherical Mercator) projection. This method is appropriate when used in conjuction with web maps. greatcircle: uses PostGIS ST_DWithin spatial query on a geography column, using great circle distances. point: simple test if point is inside polygons (e.g., radius=0) These methods assume the geometries are in a Geography column. Edge cases across the dateline are handled correctly. Different methods are needed if a regular Geometry column is used in order to handle cases across the dateline.""" mpa_list = () default_method = 'webmercator' try: lon = float(request.GET['lon']) lat = float(request.GET['lat']) try: radius = float(request.GET['radius']) except: radius = 225.0 # km try: method = request.GET['method'] or default_method # set default if empty string passed except (KeyError): method = default_method if method not in ('point', 'greatcircle', 'webmercator', 'webmercator_buffer', 'webmercator_box', 'webmercator_simple'): raise LookupMethodError('Unknown or malformed lookup method passed in GET query string.') if (radius == 0): method = 'point' except: # Bad input, return empty list return render(request, 'wdpa/mpalookup.json', { 'mpa_list': mpa_list, }, content_type='application/json; charset=utf-8') else: # We need to normalize the longitude into the range -180 to 180 so we don't # make the cast to PostGIS Geography type complain point = geos.Point(normalize_lon(lon), lat, srid=gdal.SpatialReference('WGS84').srid) # srid=4326 , WGS84 geographic if (method == 'webmercator'): if (normalize_lon(lon) < 0): lon360 = normalize_lon(lon) + 360 else: lon360 = normalize_lon(lon) - 360 point360 = geos.Point(lon360, lat, srid=gdal.SpatialReference('WGS84').srid) point.transform(900913) # Google Spherical Mercator srid point360.transform(900913) #mpa_list = WdpaPolygon.objects.filter(geom_smerc__dwithin=(point, Distance(km=radius))).defer(*WdpaPolygon.get_geom_fields()) mpa_list = WdpaPolygon.objects.filter(Q(geom_smerc__dwithin=(point, Distance(km=radius))) | Q(geom_smerc__dwithin=(point360, Distance(km=radius)))).defer(*WdpaPolygon.get_geom_fields()) search = point elif (method == 'webmercator_buffer'): point.transform(900913) # Google Spherical Mercator srid searchbuffer = point.buffer(radius * 1000) # convert km to m, create buffer mpa_list = WdpaPolygon.objects.filter(geog__intersects=searchbuffer).defer(*WdpaPolygon.get_geom_fields()) search = searchbuffer elif (method == 'webmercator_box'): point.transform(900913) # Google Spherical Mercator srid searchbuffer = point.buffer(radius * 1000) mpa_list = WdpaPolygon.objects.filter(geog__intersects=searchbuffer.envelope).defer(*WdpaPolygon.get_geom_fields()) # use simple bounding box instead search = searchbuffer.envelope elif (method == 'webmercator_simple'): point.transform(900913) # Google Spherical Mercator srid searchbuffer = point.buffer(radius * 1000, quadsegs=2) # simple buffer with 2 segs per quarter circle mpa_list = WdpaPolygon.objects.filter(geog__intersects=searchbuffer).defer(*WdpaPolygon.get_geom_fields()) search = searchbuffer elif (method == 'greatcircle'): mpa_list = WdpaPolygon.objects.filter(geog__dwithin=(point, Distance(km=radius))).defer(*WdpaPolygon.get_geom_fields()) search = point elif (method == 'point'): mpa_list = WdpaPolygon.objects.filter(geog__intersects=point).defer(*WdpaPolygon.get_geom_fields()) search = point candidate_radius = radius * 2.2 # We're using big icons on a point, this let's us catch it better mpa_candidate_list = MpaCandidate.objects.filter(geog__dwithin=(point, Distance(km=candidate_radius))).defer(*MpaCandidate.get_geom_fields()) search.transform(4326) return render(request, 'wdpa/mpalookup.json', { 'search': search.coords, 'mpa_list': mpa_list, 'mpa_candidate_list': mpa_candidate_list, }, content_type='application/json; charset=utf-8')