Skip to main content
 首页 » 编程设计

python之GeoJSON 数据不包含有意义的数据 GeoDjango

2024年11月24日26Leo_wl

我正在使用 vectorformats 在我的 map 上显示 GeoDjango 数据,遵循 this resource .我的 views.py 文件中有这个:

def geojsonFeed(request): 
    querySet = WorldBorder.objects.filter() 
    djf = Django.Django(geodjango="mpoly", properties=['name', 'iso3']) 
    geoj = GeoJSON.GeoJSON() 
    s = geoj.encode(djf.decode(querySet)) 
    return HttpResponse(s) 

但是响应看起来像这样

["type", "features", "crs"] 

任何人都可以帮助我确定我的代码有什么问题吗?

更新:添加了 WorldBorder 模型

class WorldBorder(models.Model): 
    # Regular Django fields corresponding to the attributes in the 
    # world borders shapefile. 
    name = models.CharField(max_length=50) 
    area = models.IntegerField() 
    pop2005 = models.IntegerField('Population 2005') 
    fips = models.CharField('FIPS Code', max_length=2) 
    iso2 = models.CharField('2 Digit ISO', max_length=2) 
    iso3 = models.CharField('3 Digit ISO', max_length=3) 
    un = models.IntegerField('United Nations Code') 
    region = models.IntegerField('Region Code') 
    subregion = models.IntegerField('Sub-Region Code') 
    lon = models.FloatField() 
    lat = models.FloatField() 
 
    # GeoDjango-specific: a geometry field (MultiPolygonField) 
    mpoly = models.MultiPolygonField() 
 
    # Returns the string representation of the model. 
    def __str__(self): 
        return self.name 

我正在使用 Django 2.1.7

更新 2:

>>> print(querySet) 
 
<QuerySet [<WorldBorder: Antigua and Barbuda>, <WorldBorder: Algeria>, <WorldBorder: Azerbaijan>, <WorldBorder: Albania>, <WorldBorder: Anguilla>, <WorldBorder: Armenia>, <WorldBorder: Angola>, <WorldBorder: American Samoa>, <WorldBorder: Argentina>, <WorldBorder: Australia>, <WorldBorder: Andorra>, <WorldBorder: Gibraltar>, <WorldBorder: Bahrain>, <WorldBorder: Barbados>, <WorldBorder: Bermuda>, <WorldBorder: Bahamas>, <WorldBorder: Bangladesh>, <WorldBorder: Brunei Darussalam>, <WorldBorder: Canada>, <WorldBorder: Cambodia>, '...(remaining elements truncated)...']> 

请您参考如下方法:

确认非空查询集后编辑:

我发现了问题,它与 vectorformats 模块的核心代码有关。

具体来说,在 GeoJSON.encode 中 on this specific line :

if to_string: 
    result = json_dumps(list(result_data)) 

list() 导致了问题。

让我们用一个最小的例子重现这个问题:

>>> import json 
>>> test = {'a': 5, 'b': [1, 2, 3], 'c': {'e': 2, 'f': 5}} 
>>> list(test) 
['a', 'b', 'c'] 

在这里我们看到与问题中的行为完全相同的行为。让我们更进一步:

>>> json.dumps(list(test)) 
'["a", "b", "c"]' 

但是没有list():

>>> json.dumps(test) 
'{"a": 5, "b": [1, 2, 3], "c": {"e": 2, "f": 5}}' 

因此围绕这个问题有 2 种可能的解决方案:

  1. 更改 vectorformat 代码,删除 list() 调用。
  2. 使用to_string=False 调用encode 方法并自行“jsonify”生成的字典,如下所示:

    import json 
     
    def geojsonFeed(request): 
        queryset = WorldBorder.objects.all() 
        djf = Django.Django(geodjango="mpoly", properties=['name', 'iso3']) 
        geoj = GeoJSON.GeoJSON() 
        s = geoj.encode(djf.decode(queryset), to_string=False) 
        return HttpResponse(json.dumps(s)) 
    

通过快速研究您的模块,它似乎按预期工作,所以这不是原因。 看看 GeoJSON.encode()方法:

def encode(self, features, to_string=True, **kwargs): 
    """ 
    Encode a list of features to a JSON object or string. 
    to_string determines whethr it should convert the result to 
    a string or leave it as an object to be encoded later 
    """ 
    results = [] 
    result_data = None 
    for feature in features: 
        data = self.encode_feature(feature) 
        for key,value in data['properties'].items(): 
            if value and isinstance(value, str):  
                data['properties'][key] = str(value) 
        results.append(data) 
 
   result_data = { 
                   'type':'FeatureCollection', 
                   'features': results, 
                   'crs': self.crs 
                  } 
 
   if to_string: 
        result = json_dumps(list(result_data)) 
   else: 
        result = result_data 
   return result 

result_data 具有结构 ["type", "features", "crs"] 并且它被转换为 json 列表,因为您有 to_string 参数默认为 True。

我能想到的你的问题的唯一原因是 querySet = WorldBorder.objects.filter() 查询是空。

顺便说一句,通过使用不带参数的 filter(),您会得到与 all() 查询类似的结果。