[PYTHON] Comment afficher le maillage régional du Government Statistics Office (eStat) dans un navigateur Web

Aperçu

Les statistiques de maillage de surface divisent la zone en zones de maillage sans espaces en fonction de la latitude et de la longitude, et organisent les données statistiques dans chaque zone.

メッシュ.png

démo: http://needtec.sakura.ne.jp/estat/population http://needtec.sakura.ne.jp/tokuraku/passenger.html

Les informations sur lesquelles ces données sont basées sont obtenues auprès du Government Statistics Office (estat). J'avais l'habitude de dessiner avec matplotlib en Python, mais maintenant je peux l'afficher dans le navigateur.

** Utilisons l'API de la fenêtre générale des statistiques gouvernementales (e-Stat) ** http://qiita.com/mima_ita/items/44f358dc1bc4000d365d

Veuillez vous référer à ce qui suit pour plus de détails sur la façon d'obtenir le maillage régional. http://www.stat.go.jp/data/mesh/pdf/gaiyo1.pdf

Flux jusqu'au dessin des données

Il est trop tard pour contacter la fenêtre des statistiques du gouvernement chaque fois que vous dessinez, la procédure jusqu'au dessin des données est donc divisée comme suit.

  1. Obtenir des informations de maillage régional associées à une certaine statistique à partir de la fenêtre des statistiques gouvernementales
  2. Enregistrer dans spatialite
  3. Faites en sorte que le serveur Web renvoie les informations de maillage au format geojson sur demande.
  4. Du côté de l'écran, peignez uniquement la zone nécessaire en fonction du geojson obtenu en demandant au serveur Web.

Effectuez ces étapes en Python côté serveur et en JavaScript côté client.

Le code réel peut être obtenu à partir de ce qui suit. https://github.com/mima3/estat

Veuillez vous référer à ce qui suit pour l'explication de spatialite. ** Essayez d'utiliser Spatia Lite, qui stocke des informations spatiales telles que des cartes dans SQLite ** http://qiita.com/mima_ita/items/64f6c2b8bb47c4b5b391

Création d'une base de données pour stocker des maillages régionaux

L'implémentation de la base de données qui stocke les informations statistiques présentées ici est le code suivant. https://github.com/mima3/estat/blob/master/estat_db.py

Structure de la table

Le tableau de stockage du maillage de la région estat est le suivant.

database.png

** Nom de la table: Stat ** Une table qui stocke des informations sur les statistiques

Nom de colonne Moule La description
stat_id TextField Clé principale. ID statistique
stat_name TextField Nom des statistiques gouvernementales
stat_name_code TextField Code de nom des statistiques gouvernementales
gov_org TextField Nom du créateur
gov_org_code TextField Code du nom de l'institution de création
survey_date TextField Date de l'enquête
title TextField Titre du tableau statistique

** Nom de la table: StatValue ** Stockez la valeur de chaque statistique

Nom de colonne Moule La description
id PrimaryKeyField ID de l'incrémentation automatique
stat_id TextField ID statistique
value TextField Valeur statistique

** Nom de la table: StatValueAttr ** Stocke les valeurs d'attribut associées aux valeurs de chaque statistique

Nom de colonne Moule La description
id PrimaryKeyField ID de l'incrémentation automatique
stat_id TextField ID statistique
stat_value_id INT Clé externe de l'identifiant de StatValue
attr_name TextField Nom d'attribut
attr_value TextField Valeur d'attribut

** Nom de la table: MapArea ** Stocker le polygone dans la zone d'attributs

Nom de colonne Moule La description
id PrimaryKeyField ID de l'incrémentation automatique
stat_id TextField ID statistique
stat_val_attr_id INT ID de StatValueAttr
geometry Polygon Informations sur la géométrie

Comment créer une table en Python

Le code réel lors de la création avec peewee en python est le suivant.

estat_db.py


# -*- coding: utf-8 -*-
import os
from peewee import *
from playhouse.sqlite_ext import SqliteExtDatabase
from estat_go_jp import *
import jpgrid


database_proxy = Proxy()  # Create a proxy for our db.

SRID = 4326


class PolygonField(Field):
    db_field = 'polygon'


class PointField(Field):
    db_field = 'point'


class LineStringField(Field):
    db_field = 'linestring'


class MultiPolygonField(Field):
    db_field = 'multipolygon'


class MultiPointField(Field):
    db_field = 'multipoint'


class MultiLineStringField(Field):
    db_field = 'multilinestring'


class Stat(Model):
    """
Modèle de stockage des statistiques
    """
    stat_id = TextField(primary_key=True)
    stat_name = TextField()
    stat_name_code = TextField()
    gov_org = TextField()
    gov_org_code = TextField()
    #statistics_name = TextField()
    #cycle = TextField()
    survey_date = TextField()
    #open_date = TextField()
    #small_area = TextField()
    title = TextField()

    class Meta:
        database = database_proxy


class StatValue(Model):
    """
Modèle de stockage des valeurs statistiques
    """
    id = PrimaryKeyField()
    stat_id = TextField(index=True, unique=False)
    value = TextField()

    class Meta:
        database = database_proxy


class StatValueAttr(Model):
    """
Modèle pour stocker les valeurs d'attributs statistiques
    """
    id = PrimaryKeyField()
    stat_id = TextField()
    stat_value = ForeignKeyField(
        db_column='stat_value_id',
        rel_model=StatValue,
        to_field='id'
    )
    attr_name = TextField()
    attr_value = TextField()

    class Meta:
        database = database_proxy
        indexes = (
            (('stat_id', 'stat_value'), False),
            (('stat_id', 'stat_value', 'attr_name'), False),
        )


class MapArea(Model):
    """
Modèle pour stocker Polygon dans la zone de valeur d'attribut des statistiques
    """
    id = PrimaryKeyField()
    stat_id = TextField()
    stat_val_attr = ForeignKeyField(
        db_column='stat_val_attr_id',
        rel_model=StatValueAttr,
        to_field='id'
    )
    geometry = PolygonField()

    class Meta:
        database = database_proxy
        indexes = (
            (('stat_id', 'stat_val_attr'), True),
        )


class idx_MapArea_Geometry(Model):
    pkid = PrimaryKeyField()
    xmin = FloatField()
    xmax = FloatField()
    ymin = FloatField()
    ymax = FloatField()

    class Meta:
        database = database_proxy


def connect(path, spatialite_path, evn_sep=';'):
    """
Se connecter à la base de données
    @chemin param chemin sqlite
    @param spatialite_path mod_Chemin vers spatialite
    @param env_sep Caractère de connexion PATH variable d'environnement WINDOWS;LINUX:
    """
    os.environ["PATH"] = os.environ["PATH"] + evn_sep + os.path.dirname(spatialite_path)
    db = SqliteExtDatabase(path)
    database_proxy.initialize(db)
    db.field_overrides = {
        'polygon': 'POLYGON',
        'point': 'POINT',
        'linestring': 'LINESTRING',
        'multipolygon': 'MULTIPOLYGON',
        'multipoint': 'MULTIPOINT',
        'multilinestring': 'MULTILINESTRING',
    }
    db.load_extension(os.path.basename(spatialite_path))


def setup(path, spatialite_path, evn_sep=';'):
    """
Créer une base de données
    @chemin param chemin sqlite
    @param spatialite_path mod_Chemin vers spatialite
    @param env_sep Caractère de connexion PATH variable d'environnement WINDOWS;LINUX:
    """
    connect(path, spatialite_path, evn_sep)

    database_proxy.create_tables([Stat, StatValue, StatValueAttr], True)
    database_proxy.get_conn().execute('SELECT InitSpatialMetaData()')

    #La table de géométrie doit être implémentée directement.
    database_proxy.get_conn().execute("""
        CREATE TABLE IF NOT EXISTS "MapArea" (
          "id" INTEGER PRIMARY KEY AUTOINCREMENT,
          "stat_id" TEXT,
          "stat_val_attr_id" INTEGER ,
          FOREIGN KEY(stat_val_attr_id) REFERENCES StatValueAttr(id));
    """)

    database_proxy.get_conn().execute("""
        CREATE INDEX IF NOT EXISTS "ix_MapArea_stat_id" ON MapArea(stat_id);
    """)

    database_proxy.get_conn().execute("""
        CREATE INDEX IF NOT EXISTS "ix_MapArea_stat_id_stat_val_attr_id" ON MapArea(stat_id, stat_val_attr_id);
    """)

    database_proxy.get_conn().execute("""
        Select AddGeometryColumn ("MapArea", "Geometry", ?, "POLYGON", 2);
    """, (SRID,))

    database_proxy.get_conn().execute("""
        SELECT CreateSpatialIndex("MapArea", "geometry")
    """)

Je crée une table avec la fonction de configuration. Si vous n'incluez pas la géométrie, peewee générera la table avec le code suivant.

database_proxy.create_tables([Stat, StatValue, StatValueAttr], True)

Mais si vous souhaitez inclure une colonne de géométrie, vous devez l'implémenter vous-même, comme ceci:

    #La table de géométrie doit être implémentée directement.
    database_proxy.get_conn().execute("""
        CREATE TABLE IF NOT EXISTS "MapArea" (
          "id" INTEGER PRIMARY KEY AUTOINCREMENT,
          "stat_id" TEXT,
          "stat_val_attr_id" INTEGER ,
          FOREIGN KEY(stat_val_attr_id) REFERENCES StatValueAttr(id));
    """)

    database_proxy.get_conn().execute("""
        CREATE INDEX IF NOT EXISTS "ix_MapArea_stat_id" ON MapArea(stat_id);
    """)

    database_proxy.get_conn().execute("""
        CREATE INDEX IF NOT EXISTS "ix_MapArea_stat_id_stat_val_attr_id" ON MapArea(stat_id, stat_val_attr_id);
    """)

    database_proxy.get_conn().execute("""
        Select AddGeometryColumn ("MapArea", "Geometry", ?, "POLYGON", 2);
    """, (SRID,))

    database_proxy.get_conn().execute("""
        SELECT CreateSpatialIndex("MapArea", "geometry")
    """)

Ce code crée une table avec des colonnes non géométriques, puis ajoute une colonne géométrique avec "AddGeometryColumn" et l'indexe avec "CreateSpatialIndex".

L'index créé pour la géométrie est une table virtuelle et ne peut pas être utilisé à partir de Peewee. Lorsque vous utilisez l'index, vous devez écrire vous-même le SQL.

Comment importer des statistiques dans une base de données en Python

Dans le maillage de la région eStat, une statistique est divisée pour chaque maillage principal et possède un ID statistique. Par exemple, les identifiants statistiques suivants peuvent être obtenus à partir des informations statistiques de "2010 National Census-World Survey System (1KM Mesh) 20101001".

・ T000608M3622 ・ T000608M3623 ・ T000608M3624 ・ T000608M3653 Abréviation

Cet ID est créé à partir de "T000608" et du code de maillage principal.

En d'autres termes, les étapes suivantes sont nécessaires pour obtenir des statistiques de maillage régional.

  1. Obtenez toutes les statistiques pertinentes avec l'API getStatsList d'eStat.
  2. Obtenez la valeur de chaque ID statistique avec l'API getStatsData d'eStat.
  3. Lors du stockage dans DB, recherchez la plage de longitude et de latitude à partir du code de maillage et enregistrez-la sous forme de polygone.
  4. Répétez 2-3 pour tous les ID statistiques

Obtenez toutes les statistiques pertinentes avec l'API getStatesList

La fonction pour exécuter l'API getStatesList pour obtenir tous les identifiants statistiques liés au «Système national d'enquête mondiale de recensement de 2010 (1KM Mesh) 20101001» est implémentée comme suit.

Source de référence: https://github.com/mima3/estat/blob/master/estat_go_jp.py

estat_go_jp.py


def get_stats_list(api_key, search_kind, key_word):
    """
Rechercher des statistiques
    @param api_clé API clé
    @param search_kind Type de statistiques
    @param key_clé de recherche de mot
    """
    key_word = urllib.quote(key_word.encode('utf-8'))
    url = ('http://api.e-stat.go.jp/rest/1.0/app/getStatsList?appId=%s&lang=J&searchKind=%s&searchWord=%s' % (api_key, search_kind, key_word))
    req = urllib2.Request(url)
    opener = urllib2.build_opener()
    conn = opener.open(req)
    cont = conn.read()
    parser = etree.XMLParser(recover=True)
    root = etree.fromstring(cont, parser)
    ret = []
    data_list = root.find('DATALIST_INF')
    list_infs = data_list.xpath('.//LIST_INF')
    for list_inf in list_infs:
        item = {
            'id': trim_data(list_inf.get('id'))
        }
        stat_name = list_inf.find('STAT_NAME')
        if stat_name is not None:
            item['stat_name'] = trim_data(stat_name.text)
            item['stat_name_code'] = trim_data(stat_name.get('code'))

        gov_org = list_inf.find('GOV_ORG')
        if gov_org is not None:
            item['gov_org'] = trim_data(gov_org.text)
            item['gov_org_code'] = trim_data(gov_org.get('code'))

        statistics_name = list_inf.find('STATISTICS_NAME')
        if statistics_name is not None:
            item['statistics_name'] = trim_data(statistics_name.text)

        title = list_inf.find('TITLE')
        if title is not None:
            item['title'] = trim_data(title.text)

        cycle = list_inf.find('CYCLE')
        if cycle is not None:
            item['cycle'] = cycle.text

        survey_date = list_inf.find('SURVEY_DATE')
        if survey_date is not None:
            item['survey_date'] = trim_data(survey_date.text)

        open_date = list_inf.find('OPEN_DATE')
        if open_date is not None:
            item['open_date'] = trim_data(open_date.text)

        small_area = list_inf.find('SMALL_AREA')
        if small_area is not None:
            item['small_area'] = trim_data(small_area.text)

        ret.append(item)
    return ret

Fondamentalement, les contenus acquis par urllib2 sont analysés par lxml et stockés dans le répertoire.

Obtenez la valeur de chaque ID de statistiques avec l'API getStatsData.

Pour obtenir la valeur de chaque ID statistique, exécutez la commande get_stats_id_value () suivante.

Source de référence: https://github.com/mima3/estat/blob/master/estat_go_jp.py

estat_go_jp.py


def get_meta_data(api_key, stats_data_id):
    """
Obtenir des méta-informations
    """
    url = ('http://api.e-stat.go.jp/rest/1.0/app/getMetaInfo?appId=%s&lang=J&statsDataId=%s' % (api_key, stats_data_id))
    req = urllib2.Request(url)
    opener = urllib2.build_opener()
    conn = opener.open(req)
    cont = conn.read()
    parser = etree.XMLParser(recover=True)
    root = etree.fromstring(cont, parser)
    class_object_tags = root.xpath('//METADATA_INF/CLASS_INF/CLASS_OBJ')
    class_object = {}

    for class_object_tag in class_object_tags:
        class_object_id = class_object_tag.get('id')
        class_object_name = class_object_tag.get('name')
        class_object_item = {
            'id': trim_data(class_object_id),
            'name': trim_data(class_object_name),
            'objects': {}
        }
        class_tags = class_object_tag.xpath('.//CLASS')
        for class_tag in class_tags:
            class_item = {
                'code': trim_data(class_tag.get('code')),
                'name': trim_data(class_tag.get('name')),
                'level': trim_data(class_tag.get('level')),
                'unit': trim_data(class_tag.get('unit'))
            }
            class_object_item['objects'][class_item['code']] = class_item
        class_object[class_object_id] = class_object_item
    return class_object

def _get_stats_id_value(api_key, stats_data_id, class_object, start_position, filter_str):
    """
Obtenez des statistiques
    """
    url = ('http://api.e-stat.go.jp/rest/1.0/app/getStatsData?limit=10000&appId=%s&lang=J&statsDataId=%s&metaGetFlg=N&cntGetFlg=N%s' % (api_key, stats_data_id, filter_str))
    if start_position > 0:
        url = url + ('&startPosition=%d' % start_position)
    req = urllib2.Request(url)
    opener = urllib2.build_opener()
    conn = opener.open(req)
    cont = conn.read()
    parser = etree.XMLParser(recover=True)
    root = etree.fromstring(cont, parser)
    ret = []
    row = {}
    datas = {}
    value_tags = root.xpath('//STATISTICAL_DATA/DATA_INF/VALUE')
    for value_tag in value_tags:
        row = {}
        for key in class_object:
            val = value_tag.get(key)
            if val in class_object[key]['objects']:
                text = class_object[key]['objects'][val]['name']
                row[key] = trim_data(text.encode('utf-8'))
            else:
                row[key] = val.encode('utf-8')
        row['value'] = trim_data(value_tag.text)
        ret.append(row)
    return ret


def get_stats_id_value(api_key, stats_data_id, filter):
    """
Obtenez des statistiques
    @param api_clé API clé
    @param stats_data_id ID de la table Statistiques
    @param filter_caractère de filtre str
    """
    filter_str = ''
    for key in filter:
        filter_str += ('&%s=%s' % (key, urllib.quote(filter[key].encode('utf-8'))))
    class_object = get_meta_data(api_key, stats_data_id)
    return _get_stats_id_value(api_key, stats_data_id, class_object, 1, filter_str), class_object

Vous pouvez rechercher get_stats_id_value avec un filtre, mais cette fois, nous obtiendrons tout sans filtre, alors veuillez ne pas en tenir compte.

La procédure consiste à obtenir les méta-informations des informations statistiques par get_meta_data. Cela permettra de découvrir les attributs de la statistique.

Utilisez ensuite _get_stats_id_value () pour obtenir les statistiques et les valeurs de leurs attributs.

Lors du stockage dans la base de données, recherchez la plage de longitude et de latitude à partir du code de maillage et stockez-la sous forme de polygone

Malheureusement, il n'y a pas d'informations de longitude / latitude dans les données obtenues à partir d'eStat. Par conséquent, il est nécessaire d'obtenir la longitude et la latitude à partir du code de maillage. Pour Python, il est plus facile d'utiliser les bibliothèques suivantes.

python-geohash https://code.google.com/p/python-geohash/

Cette bibliothèque peut être installée avec easy_install etc. comme indiqué ci-dessous.

easy_install python-geohash

Pour l'utiliser, spécifiez simplement le code de maillage, et la plage du code de maillage correspondant sera affichée en longitude et latitude.

import jpgrid
jpgrid.bbox('305463') #Spécifiez le code de maillage →{'s': 154.375, 'e': 20.583333333333332, 'w': 20.5, 'n': 154.5}

En utilisant ceux-ci, le code pour stocker les statistiques de maillage régional dans la base de données ressemble à ceci:

Source de référence: https://github.com/mima3/estat/blob/master/estat_db.py

estat_db.py


def import_stat(api_key, stat_id):
    """
Importer des statistiques
    @param api_key e-CLÉ API stat
    @param stat_id Statistiques ID
    """
    with database_proxy.transaction():
        MapArea.delete().filter(MapArea.stat_id == stat_id).execute()
        StatValueAttr.delete().filter(StatValueAttr.stat_id == stat_id).execute()
        StatValue.delete().filter(StatValue.stat_id == stat_id).execute()
        Stat.delete().filter(Stat.stat_id == stat_id).execute()

        tableinf = get_table_inf(api_key, stat_id)
        stat_row = Stat.create(
            stat_id=stat_id,
            stat_name=tableinf['stat_name'],
            stat_name_code=tableinf['stat_name_code'],
            title=tableinf['title'],
            gov_org=tableinf['gov_org'],
            gov_org_code=tableinf['gov_org_code'],
            survey_date=tableinf['survey_date']
        )
        values, class_object = get_stats_id_value(api_key, stat_id, {})
        for vdata in values:
            if not 'value' in vdata:
                continue
            value_row = StatValue.create(
                stat_id=stat_id,
                value=vdata['value']
            )
            for k, v in vdata.items():
                stat_val_attr = StatValueAttr.create(
                    stat_id=stat_id,
                    stat_value=value_row,
                    attr_name=k,
                    attr_value=v
                )
                if k == 'area':
                    #Code de maillage
                    meshbox = jpgrid.bbox(v)
                    database_proxy.get_conn().execute(
                        'INSERT INTO MapArea(stat_id, stat_val_attr_id, geometry) VALUES(?,?,BuildMBR(?,?,?,?,?))',
                        (stat_id, stat_val_attr.id, meshbox['s'], meshbox['e'], meshbox['n'], meshbox['w'], SRID)
                    )
        database_proxy.commit()

Si le nom de l'attribut est area, les informations de géométrie sont stockées dans MapArea en tant que maillage de région. Lors de l'utilisation de R-Index, il est difficile de fonctionner avec l'ORM de Peewee, donc l'instruction SQL est écrite directement ici.

Script pour l'importation

Le script d'importation utilisant ce qui précède est le suivant.

https://github.com/mima3/estat/blob/master/import_estat.py

Pour l'utiliser, spécifiez API_KEY, le titre des statistiques, le chemin vers mod_spatialite.dll et le chemin vers la base de données.

python import_estat.py API_KEY 2 2010 National Census-World Survey System(Maille 1KM)20101001  C:\tool\spatialite\mod_spatialite-4.2.0-win-x86\mod_spatialite.dll estat.sqlite

Ce script traite des codes de caractères avec cp932 pour Windows, veuillez donc le modifier en fonction de votre terminal.

Renvoie les informations de maillage régional en tant que GeoJSON sur le serveur Web

Ensuite, nous expliquerons comment renvoyer le maillage de région de la plage spécifiée en tant que GeoJSON sur le serveur Web. J'utilise Bottle ici, mais je pense que vous pouvez utiliser n'importe quel framework Web que vous aimez, et vous n'aurez peut-être même pas besoin d'utiliser un framework Web.

Bottle: Python Web Framework http://bottlepy.org/docs/dev/index.html

Tout d'abord, spécifiez la plage et écrivez le code pour obtenir le maillage de surface correspondant à partir de la base de données.

estat_db.py


def get_mesh_stat(stat_id_start_str, attr_value, xmin, ymin, xmax, ymax):
    """
Obtenez des statistiques régionales de maillage
    @param stat_id_start_str Statistics ID caractère de début Obtenez tous les ID commençant par ce caractère.
    @param attr_Valeur à réduire en valeur cat01
    @plage d'acquisition param xmin
    @plage d'acquisition param ymin
    @plage d'acquisition param xmax
    @param ymax Plage d'acquisition
    """
    rows = database_proxy.get_conn().execute("""
        SELECT
          statValue.value,
          AsGeoJson(MapArea.Geometry)
        FROM
          MapArea
          inner join idx_MapArea_Geometry ON pkid = MapArea.id AND xmin > ? AND ymin > ? AND xmax < ? AND ymax < ?
          inner join statValueAttr ON MapArea.stat_val_attr_id = statValueAttr.id
          inner join statValueAttr AS b ON b.stat_value_id = statValueAttr.stat_value_id AND b.attr_value = ?
          inner join statValue ON statValue.id = b.stat_value_id
        WHERE
          MapArea.stat_id like ?;
    """, (xmin, ymin, xmax, ymax, attr_value, stat_id_start_str + '%'))
    ret = []
    for r in rows:
        ret.append({
            'value': r[0],
            'geometory': r[1]
        })
    return ret

La géométrie est convertie en GeoJSON avec AsGeoJson (MapArea.Geometry) pour la traiter comme GeoJSON. Combinez cela et renvoyez-le au client en tant que GeoJSON unique, comme indiqué ci-dessous.

Source de référence: https://github.com/mima3/estat/blob/master/application.py

application.py


@app.get('/json/get_population')
def getPopulation():
    stat_id = request.query.stat_id
    swlat = request.query.swlat
    swlng = request.query.swlng
    nelat = request.query.nelat
    nelng = request.query.nelng
    attrval = request.query.attr_value

    ret = estat_db.get_mesh_stat(stat_id, attrval, swlng, swlat, nelng, nelat)
    res = {'type': 'FeatureCollection', 'features': []}
    for r in ret:
        item = {
            'type': 'Feature',
            'geometry': json.loads(r['geometory']),
            'properties': {'value': r['value']}
        }
        res['features'].append(item)
    response.content_type = 'application/json;charset=utf-8'
    return json.dumps(res)

Cela vous permettra de traiter des demandes telles que:

http://needtec.sakura.ne.jp/estat/json/get_population?stat_id=T000608&attr_value=%E4%BA%BA%E5%8F%A3%E7%B7%8F%E6%95%B0&swlat=35.503426100823496&swlng=139.53192492382811&nelat=35.83811583873688&nelng=140.08124133007811

réponse:

{"type": "FeatureCollection", "features": [{"geometry": {"type": "Polygon", "coordinates": [[[139.5374999999999, 35.6], [139.5499999999999, 35.6], [139.5499999999999, 35.60833333333333], [139.5374999999999, 35.60833333333333], [139.5374999999999, 35.6]]]},Abréviation

Exemple de dessin d'un maillage régional à l'aide de Google Map

Ici, nous allons décrire un exemple de dessin d'un maillage régional à l'aide de Google Map.

mesh.png

démo: http://needtec.sakura.ne.jp/estat/population

En utilisant addGeoJSON dans GoogleMap, vous pouvez dessiner n'importe quel GeoJSON sur GoogleMAP.

population.js


          features  = map.data.addGeoJson(result);
          var max = 0;
          for (var i = 0; i < features.length; i++) {
            if (max < features[i].getProperty('value')) {
              max = features[i].getProperty('value');
            }
          }
          map.data.setStyle(styleFeature(max));

À ce stade, vous pouvez spécifier le style GeoJSON avec setStyle. Dans cet exemple, la densité de couleur est modifiée en fonction de la valeur de la propriété.

population.js


      var styleFeature = function(max) {
        var colorScale = d3.scale.linear().domain([0, max]).range(["#CCFFCC", "red"]);
        return function(feature) {
          return {
            strokeWeight : 1,
            fillColor: colorScale(+feature.getProperty('value')),
            fillOpacity: 0.5
          };
        };
      }

référence: ** Afficher les données GeoJSON sur Google Map ** http://shimz.me/blog/google-map-api/3445

Dessiner une grande zone à la fois est lourd, la fonction d'agrandissement est donc désactivée.

Exemple de dessin d'un maillage régional à l'aide de D3.js

Ici, D3.js est utilisé pour décrire un exemple de dessin d'un maillage régional à l'aide de SVG.

メッシュ.png

démo: http://needtec.sakura.ne.jp/tokuraku/passenger.html

passenger.js


$('#selMesh').change(function() {
  svgMeshGrp
     .attr('class', 'tracts')
     .selectAll('rect')
     .data([])
     .exit()
     .remove();

  var sel = $('#selMesh').val();
  if (!sel) {
    return;
  }

  function drawMesh(json) {
    console.log(json);
    var max = 0;
    for (var i = 0; i < json.features.length; ++i) {
      var v = parseInt(json.features[i].properties.value);
      if (max < v) {
        max = v;
      }
    }
    console.log(max);
    var colorScale = d3.scale.linear().domain([0, max]).range([0.0, 0.8]);
    svgMeshGrp
       .attr('class', 'tracts')
       .selectAll('rect')
       .data(json.features)
       .enter()
       .append('rect')
       .attr('x', function(d, i) {
         var extX = d3.extent(d.geometry.coordinates[0], function(d) { return d[0];});
         var extY = d3.extent(d.geometry.coordinates[0], function(d) { return d[1];});
         var pt = projection([extX[0], extY[0]]);
         return pt[0];
       })
       .attr('y', function(d) {
         var extX = d3.extent(d.geometry.coordinates[0], function(d) { return d[0];});
         var extY = d3.extent(d.geometry.coordinates[0], function(d) { return d[1];});
         var pt = projection([extX[0], extY[0]]);
         return pt[1];
       })
       .attr('width', function(d) {
         var extX = d3.extent(d.geometry.coordinates[0], function(d) { return d[0];});
         var extY = d3.extent(d.geometry.coordinates[0], function(d) { return d[1];});
         var ptMin = projection([extX[0], extY[0]]);
         var ptMax = projection([extX[1], extY[1]]);
         return Math.abs(ptMax[0] - ptMin[0]);
       })
       .attr('height', function(d) {
         var extX = d3.extent(d.geometry.coordinates[0], function(d) { return d[0];});
         var extY = d3.extent(d.geometry.coordinates[0], function(d) { return d[1];});
         var ptMin = projection([extX[0], extY[0]]);
         var ptMax = projection([extX[1], extY[1]]);
         return Math.abs(ptMax[1] - ptMin[1]);
       })
       .attr('fill-opacity', function(d) {
         console.log('color' , d.properties.value, colorScale(d.properties.value));
         return colorScale(d.properties.value);
       })
       .attr('fill' , '#00f');
  }

  if (stat_dict[sel].json) {
    drawMesh(stat_dict[sel].json);
  } else {
    $.blockUI({ message: '<img src="/railway_location/img/loading.gif" />' });
    var api = encodeURI(util.format('/estat/json/get_population?swlat=%d&swlng=%d&nelat=%d&nelng=%d&stat_id=%s&attr_value=%s',
      swlat, swlng, nelat, nelng, stat_dict[sel].id, stat_dict[sel].attrval
    ));
    d3.json(api, function(json) {
      drawMesh(json);
      stat_dict[sel].json = json;
      $.unblockUI();
    });
  }
}).keyup(function() {
  $(this).blur().focus();
});

Le point à noter ici est que GeoJSON est utilisé pour dessiner avec rect au lieu de dessiner comme chemin. L'ajout de 1000 chemins à svg le rend plus lourd, mais rect est plus léger. Le maillage de la zone étant toujours carré, il est préférable de dessiner avec rect.

Résumé

J'ai expliqué comment décrire le maillage régional dans la fenêtre des statistiques générales du gouvernement eStat. Je pense qu'il était possible de démontrer que la vitesse de traitement peut être augmentée en la stockant temporairement dans une base de données capable de stocker des informations de géométrie telles que Spatialite.

Recommended Posts

Comment afficher le maillage régional du Government Statistics Office (eStat) dans un navigateur Web
Comment afficher la date de modification d'un fichier en langage C jusqu'à nanosecondes
Comment afficher une colonne de fichiers spécifiée sous Linux (awk)
Comment déterminer l'existence d'un élément sélénium en Python
Comment vérifier la taille de la mémoire d'une variable en Python
Comment vérifier la taille de la mémoire d'un dictionnaire en Python
Comment obtenir les coordonnées de sommet d'une entité dans ArcPy
[Python] Comment spécifier la position d'affichage de la fenêtre et la taille de matplotlib
[Android] Afficher des images sur le Web dans la fenêtre info de Google Map
J'ai essayé d'afficher la valeur d'altitude du DTM dans un graphique
Comment calculer la volatilité d'une marque
Comment ouvrir un navigateur Web à partir de python
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python
Comment mentionner un groupe d'utilisateurs avec une notification de mou, comment vérifier l'ID d'un groupe d'utilisateurs
Comment compter le nombre d'éléments dans Django et sortir dans le modèle
Un mémorandum expliquant comment exécuter la commande magique! Sudo dans Jupyter Notebook
Comment afficher dans toute la fenêtre lors de la définition de l'image d'arrière-plan avec tkinter
Comment obtenir une liste de fichiers dans le même répertoire avec python
Comment obtenir le nombre de chiffres en Python
Utilisons l'API de la fenêtre générale des statistiques gouvernementales (e-Stat)
Comment afficher plusieurs images d'une galaxie en tuiles
Comment afficher DataFrame sous forme de tableau dans Markdown
Comment identifier l'élément avec le plus petit nombre de caractères dans une liste Python?
Comment vérifier en Python si l'un des éléments d'une liste est dans une autre liste
[Ubuntu] Comment supprimer tout le contenu du répertoire
Comment trouver le nombre optimal de clusters pour les k-moyennes
Comment utiliser la méthode __call__ dans la classe Python
[Super facile! ] Comment afficher le contenu des dictionnaires et des listes incluant le japonais en Python
Comment compter rapidement la fréquence d'apparition des caractères à partir d'une chaîne de caractères en Python?
Comment développer dans un environnement virtuel Python [Memo]
Comment générer une requête à l'aide de l'opérateur IN dans Django
Comment afficher une liste des versions installables avec pyenv
Comment obtenir la dernière (dernière) valeur d'une liste en Python
Lors de la résolution de l'exercice d'introduction aux statistiques 12.10, vérifiez comment dessiner un diagramme de dispersion dans les pandas.
Comment obtenir une liste d'exceptions intégrées pour python
Comment trouver le coefficient de mise à l'échelle d'une ondelette bipolaire
Comment représenter la distribution de la composition bactérienne à partir des données d'analyse Qiime2 dans un diagramme de moustaches
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python (version non bloquante)
Comment connecter le contenu de la liste dans une chaîne de caractères
Comment prendre une capture d'écran de l'écran Chrome (l'empêcher de se couper au milieu)
Envoie le résultat de l'analyse morphologique avec Mecab vers un navigateur WEB compatible avec le serveur Sakura / UTF-8
[PyQt x pySerial] Afficher une liste des ports COM connectés au PC dans la liste déroulante
[sh] Comment stocker les résultats de l'exécution de la commande dans des variables
Comment implémenter du code Java en arrière-plan de Red Hat (Linux ONE)
Affichage en temps réel de la progression du traitement côté serveur sur le navigateur (implémentation de la barre de progression)
Comment connaître la structure interne d'un objet en Python
Comment obtenir toutes les valeurs possibles dans une expression régulière
Comment changer la couleur du seul bouton pressé avec Tkinter
[Introduction à Python] Comment utiliser l'opérateur in dans l'instruction for?
[TensorFlow 2] Comment vérifier le contenu de Tensor en mode graphique
Comment trouver l'adresse mémoire de la valeur de la trame de données Pandas
Comment afficher le résultat de sortie de la commande man Linux dans un fichier
Comment créer une grande quantité de données de test dans MySQL? ??
Créez une fonction pour obtenir le contenu de la base de données dans Go
J'ai fait une commande pour afficher un calendrier coloré dans le terminal
[NNabla] Comment supprimer le niveau intermédiaire d'un réseau prédéfini
Comment afficher les octets de la même manière en Java et Python