Bereichsnetzstatistiken unterteilen Bereiche in Netzbereiche ohne Lücken basierend auf Breiten- und Längengrad und organisieren statistische Daten in jedem Bereich.
Demo: http://needtec.sakura.ne.jp/estat/population http://needtec.sakura.ne.jp/tokuraku/passenger.html
Die Informationen, auf denen diese Daten basieren, werden vom Government Statistics Office (estat) bezogen. Früher habe ich in Python mit matplotlib gezeichnet, jetzt kann ich es im Browser anzeigen.
** Verwenden wir die API des allgemeinen Fensters für Regierungsstatistiken (e-Stat) ** http://qiita.com/mima_ita/items/44f358dc1bc4000d365d
Weitere Informationen zum Erhalt des regionalen Netzes finden Sie im Folgenden. http://www.stat.go.jp/data/mesh/pdf/gaiyo1.pdf
Es ist zu spät, sich bei jeder Zeichnung an das Statistikfenster der Regierung zu wenden. Daher ist das Verfahren bis zur Datenerfassung wie folgt unterteilt.
Führen Sie diese Schritte in Python auf der Serverseite und in JavaScript auf der Clientseite aus.
Der eigentliche Code kann aus dem Folgenden bezogen werden. https://github.com/mima3/estat
Im Folgenden finden Sie Erläuterungen zu Spatialit. ** Versuchen Sie es mit Spatia Lite, das räumliche Informationen wie Karten in SQLite speichert. ** http://qiita.com/mima_ita/items/64f6c2b8bb47c4b5b391
Die Implementierung der Datenbank, in der die hier eingeführten statistischen Informationen gespeichert sind, ist der folgende Code. https://github.com/mima3/estat/blob/master/estat_db.py
Die Tabelle zum Speichern des Estat-Regionsnetzes ist wie folgt.
** Tabellenname: Stat ** Eine Tabelle, in der Informationen zu Statistiken gespeichert sind
Spaltenname | Schimmel | Erläuterung |
---|---|---|
stat_id | TextField | Hauptschlüssel. Statistik-ID |
stat_name | TextField | Name der Regierungsstatistik |
stat_name_code | TextField | Namenscode der Regierungsstatistik |
gov_org | TextField | Name des Erstellers |
gov_org_code | TextField | Namenscode der Erstellungsinstitution |
survey_date | TextField | Umfragedatum |
title | TextField | Titel der statistischen Tabelle |
** Tabellenname: StatValue ** Speichern Sie den Wert jeder Statistik
Spaltenname | Schimmel | Erläuterung |
---|---|---|
id | PrimaryKeyField | ID des automatischen Inkrements |
stat_id | TextField | Statistik-ID |
value | TextField | Statistikwert |
** Tabellenname: StatValueAttr ** Speichert Attributwerte, die den Werten jeder Statistik zugeordnet sind
Spaltenname | Schimmel | Erläuterung |
---|---|---|
id | PrimaryKeyField | ID des automatischen Inkrements |
stat_id | TextField | Statistik-ID |
stat_value_id | INT | Externer Schlüssel der ID von StatValue |
attr_name | TextField | Attributname |
attr_value | TextField | Attributwert |
** Tabellenname: MapArea ** Speichern Sie das Polygon im Attributbereich
Spaltenname | Schimmel | Erläuterung |
---|---|---|
id | PrimaryKeyField | ID des automatischen Inkrements |
stat_id | TextField | Statistik-ID |
stat_val_attr_id | INT | ID von StatValueAttr |
geometry | Polygon | Geometrieinformationen |
Der tatsächliche Code beim Erstellen mit Peewee in Python lautet wie folgt.
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):
"""
Modell zum Speichern von Statistiken
"""
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):
"""
Modell zum Speichern statistischer Werte
"""
id = PrimaryKeyField()
stat_id = TextField(index=True, unique=False)
value = TextField()
class Meta:
database = database_proxy
class StatValueAttr(Model):
"""
Modell zum Speichern statistischer Attributwerte
"""
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):
"""
Modell zum Speichern von Polygon im Attributwertbereich der Statistik
"""
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=';'):
"""
Verbindung zur Datenbank herstellen
@param path sqlite path
@param spatialite_path mod_Weg zum Spatialit
@param env_sep Umgebungsvariable PATH Verbindungszeichen 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=';'):
"""
Datenbank erstellen
@param path sqlite path
@param spatialite_path mod_Weg zum Spatialit
@param env_sep Umgebungsvariable PATH Verbindungszeichen WINDOWS;LINUX:
"""
connect(path, spatialite_path, evn_sep)
database_proxy.create_tables([Stat, StatValue, StatValueAttr], True)
database_proxy.get_conn().execute('SELECT InitSpatialMetaData()')
#Die Geometrietabelle muss direkt implementiert werden.
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")
""")
Ich erstelle eine Tabelle mit der Setup-Funktion. Wenn Sie die Geometrie nicht angeben, generiert peewee die Tabelle mit dem folgenden Code.
database_proxy.create_tables([Stat, StatValue, StatValueAttr], True)
Wenn Sie jedoch eine Spalte mit Geometrie einfügen möchten, müssen Sie diese wie folgt selbst implementieren:
#Die Geometrietabelle muss direkt implementiert werden.
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")
""")
Dieser Code erstellt eine Tabelle mit Spalten ohne Geometrie, fügt dann eine Geometriespalte mit "AddGeometryColumn" hinzu und indiziert sie mit "CreateSpatialIndex".
Der für die Geometrie erstellte Index ist eine virtuelle Tabelle und kann nicht von Peewee aus verwendet werden. Wenn Sie den Index verwenden, müssen Sie die SQL selbst schreiben.
Im eStat-Regionsnetz wird eine Statistik für jedes primäre Netz aufgeteilt und verfügt über eine Statistik-ID. Die folgenden statistischen IDs können beispielsweise aus den statistischen Informationen des "2010 National Census-World Survey System (1KM Mesh) 20101001" abgerufen werden.
・ T000608M3622 ・ T000608M3623 ・ T000608M3624 ・ T000608M3653 Abkürzung
Diese ID wird aus "T000608" und dem primären Netzcode erstellt.
Mit anderen Worten, die folgenden Schritte sind erforderlich, um regionale Netzstatistiken zu erhalten.
Die Funktion zum Ausführen der getStatesList-API zum Abrufen aller statistischen IDs im Zusammenhang mit "2010 National Census-World Survey System (1KM Mesh) 20101001" wird wie folgt implementiert.
Referenzquelle: 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):
"""
Suche nach Statistiken
@param api_Schlüssel API-Schlüssel
@param search_Art Statistik-Typ
@param key_Wortsuchschlüssel
"""
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
Grundsätzlich werden die von urllib2 erfassten Inhalte von lxml analysiert und im Verzeichnis gespeichert.
Führen Sie den folgenden get_stats_id_value () aus, um den Wert für jede Statistik-ID abzurufen.
Referenzquelle: https://github.com/mima3/estat/blob/master/estat_go_jp.py
estat_go_jp.py
def get_meta_data(api_key, stats_data_id):
"""
Holen Sie sich Meta-Informationen
"""
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):
"""
Statistiken abrufen
"""
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):
"""
Statistiken abrufen
@param api_Schlüssel API-Schlüssel
@param stats_data_id Statistik-Tabellen-ID
@param filter_str Filterzeichen
"""
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
Sie können mit einem Filter nach get_stats_id_value suchen, aber dieses Mal erhalten wir alles ohne Filter. Bitte berücksichtigen Sie dies nicht.
Das Verfahren besteht darin, die Metainformationen der statistischen Informationen durch get_meta_data abzurufen. Dadurch wird herausgefunden, welche Attribute die Statistik hat.
Verwenden Sie dann _get_stats_id_value (), um die Statistiken und die Werte für ihre Attribute abzurufen.
Leider enthalten die von eStat erhaltenen Daten keine Längen- / Breitengradinformationen. Daher ist es notwendig, den Längen- und Breitengrad aus dem Netzcode zu erhalten. Für Python ist es einfacher, die folgenden Bibliotheken zu verwenden.
python-geohash https://code.google.com/p/python-geohash/
Diese Bibliothek kann mit easy_install usw. wie unten gezeigt installiert werden.
easy_install python-geohash
Um es zu verwenden, geben Sie einfach den Netzcode an, und der Bereich des entsprechenden Netzcodes wird in Längen- und Breitengrad angezeigt.
import jpgrid
jpgrid.bbox('305463') #Geben Sie den Netzcode an →{'s': 154.375, 'e': 20.583333333333332, 'w': 20.5, 'n': 154.5}
Mit diesen sieht der Code zum Speichern regionaler Netzstatistiken in der Datenbank folgendermaßen aus:
Referenzquelle: https://github.com/mima3/estat/blob/master/estat_db.py
estat_db.py
def import_stat(api_key, stat_id):
"""
Statistiken importieren
@param api_key e-stat API KEY
@param stat_id Statistik 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':
#Netzcode
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()
Wenn der Attributname area ist, werden die Geometrieinformationen in MapArea als Regionsnetz gespeichert. Bei Verwendung von R-Index ist es schwierig, mit Peewees ORM zu arbeiten, daher wird die SQL-Anweisung direkt hier geschrieben.
Das oben beschriebene Importskript lautet wie folgt.
https://github.com/mima3/estat/blob/master/import_estat.py
Geben Sie dazu API_KEY, den Titel der Statistik, den Pfad zu mod_spatialite.dll und den Pfad zur Datenbank an.
python import_estat.py API_SCHLÜSSEL 2 National Census-World Survey System 2010(1 km Maschenweite)20101001 C:\tool\spatialite\mod_spatialite-4.2.0-win-x86\mod_spatialite.dll estat.sqlite
Dieses Skript behandelt Zeichencodes mit cp932 für Windows. Ändern Sie es daher entsprechend Ihrem Terminal.
Als Nächstes wird erläutert, wie das Regionsnetz des angegebenen Bereichs als GeoJSON auf dem Webserver zurückgegeben wird. Ich verwende hier eine Flasche, aber ich denke, Sie können jedes Webframework verwenden, das Sie mögen, und Sie müssen möglicherweise nicht einmal ein Webframework verwenden.
Bottle: Python Web Framework http://bottlepy.org/docs/dev/index.html
Geben Sie zunächst den Bereich an und schreiben Sie den Code, um das entsprechende Flächennetz aus der Datenbank abzurufen.
estat_db.py
def get_mesh_stat(stat_id_start_str, attr_value, xmin, ymin, xmax, ymax):
"""
Erhalten Sie regionale Netzstatistiken
@param stat_id_start_str Statistik-ID-Startzeichen Ruft alle IDs ab, die mit diesem Zeichen beginnen.
@param attr_Wert, der im Wert cat01 eingegrenzt werden soll
@Parameter xmin Erfassungsbereich
@Erfassungsbereich für Parameter
@param xmax Erfassungsbereich
@param ymax Erfassungsbereich
"""
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
Geometrie wird mit AsGeoJson (MapArea.Geometry) in GeoJSON konvertiert, um sie als GeoJSON zu behandeln. Kombinieren Sie dies und geben Sie es wie unten gezeigt als einzelnes GeoJSON an den Client zurück.
Referenzquelle: 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)
Auf diese Weise können Sie Anfragen bearbeiten wie:
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
Antwort:
{"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]]]},Abkürzung
Hier beschreiben wir ein Beispiel für das Zeichnen eines regionalen Netzes mit Google Map.
Demo: http://needtec.sakura.ne.jp/estat/population
Mit addGeoJSON in GoogleMap können Sie jedes GeoJSON auf GoogleMAP zeichnen.
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));
Zu diesem Zeitpunkt können Sie den GeoJSON-Stil mit setStyle angeben. In diesem Beispiel wird die Farbdichte entsprechend dem Eigenschaftswert geändert.
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
};
};
}
Referenz: ** GeoJSON-Daten auf Google Map anzeigen ** http://shimz.me/blog/google-map-api/3445
Wenn Sie einen großen Bereich gleichzeitig zeichnen, wird dieser schwer, sodass die Vergrößerungsfunktion deaktiviert ist.
Hier wird D3.js verwendet, um ein Beispiel für das Zeichnen eines regionalen Netzes mit SVG zu beschreiben.
Demo: 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();
});
Hierbei ist zu beachten, dass GeoJSON verwendet wird, um mit rect zu zeichnen, anstatt als Pfad zu zeichnen. Das Hinzufügen von 1000 Pfaden zu svg macht es schwerer, aber rect ist leichter. Da das Flächennetz immer quadratisch ist, ist es besser, mit rect zu zeichnen.
Ich habe im allgemeinen Statistikfenster eStat der Regierung erklärt, wie das regionale Netz beschrieben wird. Ich denke, es war möglich zu demonstrieren, dass die Verarbeitungsgeschwindigkeit erhöht werden kann, indem sie vorübergehend in einer Datenbank gespeichert wird, in der Geometrieinformationen wie Spatialite gespeichert werden können.
Recommended Posts