Skip to content

Commit

Permalink
changed city ID to use geonamesID instead of slug (#29)
Browse files Browse the repository at this point in the history
* changed city ID to use geonamesID instead of slug

* fixed PR after 1st review

* fixed file downloading error for NaturalEarth dataset

* fixed NaturalEarth data test failing

* removed unrelated migrations, fixed naturalearth data importer
  • Loading branch information
skarampatakis authored and akariv committed Jun 4, 2017
1 parent 79d552c commit a089040
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 12 deletions.
37 changes: 37 additions & 0 deletions README.md
Expand Up @@ -13,6 +13,8 @@ Just a brief summary:

* contains a list of all countries in the world with country code, country continent and list of countries on the same continent;
* contains a list of all continents in the world with a list of countries for each continent;
* contains a list of all regions in the world with a list of cities for each country;
* contains a list of all cities in the world with population over 5000;
* contains a list of all currencies in the world, each currency has a list of countries where this currency is being used.

Based on https://github.com/coderholic/django-cities
Expand Down Expand Up @@ -40,6 +42,41 @@ Example: `GET /v1/countries/?continents=an`, `GET /v1/countries/?continents=an,a

Example: `GET /v1/currencies/?countries=aq`, `GET /v1/currencies/?countries=aq,af`

### Filter: cities by countries

* `/v1/cities/?countries={id}` - get cities of the particular country;
* `/v1/cities/?countries={id},{id},{id}` - get cities belong to several countries.

Example: `GET /v1/cities/?countries=gr`, `GET /v1/cities/?countries=gr,us`

### Filter: cities by regions

* `/v1/cities/?regions={id}` - get cities of the particular region;
* `/v1/cities/?regions={id},{id},{id}` - get cities belong to several regions.

Example: `GET /v1/cities/?regions=tx`, `GET /v1/cities/?countries=tx,il`

### Filter: cities by continents

* `/v1/cities/?continents={id}` - get cities of the particular continent;
* `/v1/cities/?continents={id},{id},{id}` - get cities belong to several continents.

Example: `GET /v1/cities/?continents=eu`, `GET /v1/cities/?continents=eu,af`

### Filter: cities by slug

* `/v1/cities/?slugs={slug}` - get cities matching the particular slug, ;
* `/v1/cities/?slugs={slug},{slug},{slug}` - get cities matching to several slugs.

Example: `GET /v1/cities/?slugs=athens`, `GET /v1/cities/?slugs=athens,paris`
** where slug means the name of the city in lowercase with no accents and instead of spaces, hyphens "-"

### Filter: multiple filters

You can also define multiple filters on the city endpoint.

Example: `GET /v1/cities/?slugs=athens,paris&countries=us&regions=tx`

### Filter: countries polygons by countries

* `/v1/countrypolygons/?countries={id},{id},{id}`
Expand Down
3 changes: 2 additions & 1 deletion cosmopolitan/management/commands/_django_cities.py
Expand Up @@ -177,7 +177,8 @@ def process_cities():
# one city with name Ak”yar has no slug, so we set it here
if dc_city.slug == '':
dc_city.slug = 'aky'
city = City(id=dc_city.slug.lower(),
city = City(id=dc_city.id,
slug=dc_city.slug.lower(),
name=dc_city.name,
name_std=dc_city.name_std,
location=dc_city.location,
Expand Down
8 changes: 4 additions & 4 deletions cosmopolitan/management/commands/_naturalearthdata.py
Expand Up @@ -9,7 +9,7 @@

from cosmopolitan.management.commands.service.common import prepare_data

# countrise data URL
# countries data URL
# http://naciscdn.org/naturalearth/10m/cultural/ne_10m_admin_0_countries.zip

COUNTRIES = {
Expand Down Expand Up @@ -62,11 +62,11 @@ def process_cities():
Polygon.objects.filter(type='city').delete()

for feature in data["features"]:
json_city_name = feature["properties"]["GN_ASCII"]
json_city_id = int(feature["properties"]["GEONAMEID"])
try:
if json_city_name is None:
if json_city_id is 0:
continue
city = City.objects.get(name=json_city_name)
city = City.objects.get(id=str(json_city_id))
polygon = Polygon(id="%s:%s" % ("city", city.id))
polygon.type = "city"
polygon.type_id = city.id
Expand Down
4 changes: 2 additions & 2 deletions cosmopolitan/management/commands/service/web.py
Expand Up @@ -23,9 +23,9 @@ def _already_downloaded(self):

def _retreive(self):
try:
res = requests.get(self.url, steam=True)
res = requests.get(self.url, stream=True)
with open(self.file_name, 'wb') as fd:
for chunk in r.iter_content(chunk_size):
for chunk in res.iter_content(1024 * 64):
fd.write(chunk)
except Exception as e:
sos._super_log("Was about to retreive %s, but got error: %s"
Expand Down
2 changes: 1 addition & 1 deletion cosmopolitan/management/commands/test_naturalearthdata.py
Expand Up @@ -18,7 +18,7 @@

mock_city_data = {"features": [
{"properties":
{"GN_ASCII": "City Name"},
{"GEONAMEID": "734077"},
"geometry":
{"coordinates": "12"}}]}

Expand Down
20 changes: 20 additions & 0 deletions cosmopolitan/migrations/0006_added_slug_column_in_cities_table.py
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.2 on 2017-05-25 16:26
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('cosmopolitan', '0005_polygon'),
]

operations = [
migrations.AddField(
model_name='city',
name='slug',
field=models.CharField(db_index=True, max_length=200, null=True),
),
]
3 changes: 2 additions & 1 deletion cosmopolitan/models.py
Expand Up @@ -35,9 +35,10 @@ class Region(models.Model):


class City(models.Model):
id = models.CharField(max_length=200, primary_key=True)
id = models.CharField(max_length=200, primary_key=True) # An geoNameId now
name = models.CharField(max_length=200, db_index=True, verbose_name="ascii name")
name_std = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
slug = models.CharField(max_length=200, db_index=True, null=True)
location = models.PointField()
population = models.IntegerField()
region = models.ForeignKey("cosmopolitan.Region", null=True, blank=True)
Expand Down
2 changes: 1 addition & 1 deletion cosmopolitan/serializers/common.py
Expand Up @@ -30,7 +30,7 @@ class Meta:
class CitySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = City
fields = ('id', 'url', 'name')
fields = ('id', 'url', 'name', 'slug')


class RegionSerializer(serializers.HyperlinkedModelSerializer):
Expand Down
4 changes: 2 additions & 2 deletions cosmopolitan/serializers/specific.py
Expand Up @@ -146,7 +146,7 @@ class CityListSerializer(CitySerializer):

class Meta:
model = City
fields = ('id', 'url', 'name', 'name_std', 'kind', 'country', 'region')
fields = ('id', 'url', 'name', 'name_std', 'kind', 'country', 'region', 'slug')


class CityDetailSerializer(CitySerializer):
Expand All @@ -155,7 +155,7 @@ class CityDetailSerializer(CitySerializer):

class Meta:
model = City
fields = ('id', 'url', 'name', 'name_std', 'kind', 'country',
fields = ('id', 'slug', 'url', 'name', 'name_std', 'kind', 'country',
'region', 'location', 'population', 'elevation', 'timezone')


Expand Down
17 changes: 17 additions & 0 deletions cosmopolitan/viewsets.py
Expand Up @@ -50,14 +50,31 @@ class CityViewSet(mixins.ListDetailSerializerMixin,

def get_queryset(self):
queryset = City.objects.all()
continents = self.request.query_params.get('continents', None)
regions = self.request.query_params.get('regions', None)
countries = self.request.query_params.get('countries', None)
slugs = self.request.query_params.get('slugs', None)

if slugs is not None:
slugs = slugs.split(',')
queryset = queryset.filter(slug__in=slugs)

if countries is not None:
countries = countries.split(',')
queryset = queryset.filter(country_id__in=countries)

if regions is not None:
regions = regions.split(',')
queryset = queryset.filter(region_id__in=regions)

if continents is not None:
continents = continents.split(',')
queryset = queryset.filter(continent_id__in=continents)

return queryset



class ContinentViewSet(mixins.ListDetailSerializerMixin,
viewsets.ReadOnlyModelViewSet):
model = Continent
Expand Down

0 comments on commit a089040

Please sign in to comment.