GeoDjango使用带缓冲区的LineStringField创建模型

时间:2014-07-04 08:34:05

标签: django geodjango

我创建了一个由细分组成的街道模型。每个段以Sign(模型)开始和结束。我决定使用LineStringField作为街道表示但是为了将未来的点与它相交,我想为它添加一些缓冲区,所以当用户来到街道时,我能够判断它们是否在内这条街在缓冲区内。

class Segment(models.Model):
    starts_with_sign = models.ForeignKey(Sign)
    ends_with_sign = models.ForeignKey(Sign)
    seg = models.LineStringField()

class Street(models.Model):
    name = models.CharField(max_length=200)
    is_one_way = models.BooleanField(blank=True, null=True, default=False)
    is_avenue = models.BooleanField(blank=True, null=True, default=False)
    has_public_transportation_lane = models.BooleanField(blank=True, null=True, default=False)
    parking_area = models.ForeignKey(Area) # for cities with parking areas
    segments = models.ForeignKey
    created = models.DateTimeField(auto_now_add=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name

我的问题是:

  1. 如何将此缓冲区添加到LineStringField?
  2. 如何指定标志(点) LineStringField?
  3. 使用给定的坐标,如何查询 该点在哪个段?

1 个答案:

答案 0 :(得分:0)

因此,在整天挖掘和重新思考之后,我想出了一些实施思路:

  1. 而不是为每个LineString添加缓冲区,这将使它成为一个 多边形(浪费数据空间?)并使用a执行相关多边形的点搜索 在PostGIS ST_Buffer's docs再次重复之后给出了Point (Geom.buffer上的GeoDjango)我理解将来查询会有更好(更快)的使用 使用PostGIS ST_DWithin<field>__<distance lookup>=(<geometry>, <distance value>[, 'spheroid'])开启 GeoDjango GeoQuerySets)并且在这种情况下存储Segment或street将使用LineString。
  2. 感谢this帖子,我想出了这段代码:

    class Sign(models.Model):
        name = models.CharField(max_length=10)
        gps_point = models.PointField()
        objects = models.GeoManager()
    
        def __unicode__(self):
            return self.name
    
    class Segment(models.Model):
        start_sign = models.ForeignKey(Sign, related_name='seg_start')
        end_sign = models.ForeignKey(Sign, related_name='seg_end')
        line = models.LineStringField(blank=True, null=True)
        objects = models.GeoManager()
    
        def save(self):
            super(Segment,self).save()
            if not self.line and self.start_sign and self.end_sign:
                self.line = LineString(self.start_sign.gps_point,self.end_sign.gps_point)
                self.save()
    

    所以通过覆盖save()我可以在保存完成后将LineString(self.start_sign.gps_point,self.end_sign.gps_point)分配给LineStringField。 现在我需要处理的是为段的起点分配一个开始标志,为段的结尾分配结束标志,并为我创建LineString对象:)

  3. 现在我只能通过Segment.objects.filter(line__distance_lte=(Point(lat,lon),D(m=required_distance))过滤掉相关的街道/细分。
  4. 干杯