Internationale Administrative Grenzen

Moin,

hier die Ergebnisse der letzten Auswertung:

Ausgewertet wurden DEU, MAR, PRT, PSE, QAT und RUS

DEU: +23
PRT: +84, -2
RUS: +101, -1

Gruss
Walter

Danke auf jeden Fall mal für die vielen Antworten. Ich verdaue das mal.

Gehst Du da nach einer strengen “st_contains”-Regel vor, oder machst Du schmutzige Tricks ;)? Ich erinnere mich, dass ich sowas auch mal gemacht habe, und dann blieben immer ein paar Sorgenkandidaten übrig. Dann habe ich in einem ersten Schritt auch erlaubt, dass etwas “in Karlsruhe” liegt, wenn es in einem 50-Meter-Buffer um Karlsruhe herum liegt. Und bei denen, bei denen das nichts geholfen hat (wieder mal eine Stadt, die zu 10% in Mexiko liegt und zu 90% in den USA oder so), habe ich dann die Größe der Schnittmenge mit allen drüberliegenden Adminbounds ausgerechnet und es dem zugeschlagen, in dem es “hauptsächlich” liegt…

Und damit versorge ich meine Boundaries-Karte.

Wenn es dagegen “nur” um eine Überprüfung der Grenzen auf Existenz, Korrektheit, Größenveränderungen und ähnliches geht - ohne die Verschachtelung zu erzeugen - geht das sicher einfacher und schneller. Diese tägliche Liste ist wirklich nur ein Spin-Off der Boundaries-Karte.

Der Tree hilft natürlich, viele Fehler überhaupt erst zu finden. Einerseits müssen alle Admin-Areas üblicherweise eben in einer Mutter-Area liegen. Aber auch umgekehrt ist es ein Zeichen eines möglichen Problems, wenn eine Fläche auf Adminlevel X fast komplett von Kindern auf Adminlevel X+1 oder X+2 abgedeckt ist, aber eben nur fast… solche Sachen würde ich gern sichtbar machen, aber Du wirst sicherlich zustimmen, wenn ich sage, das ist alles etwas kniffliger als es sich auf den ersten Blick anhört :wink:

Bye
Frederik

Ich arbeite mit ST_PointOnSurface() und schaue dann mit ST_Contains() nach, in welchen Boundaries dieser Punkt liegt. Damit dürfte ich wohl keine “Randschärfenprobleme” haben.

Zur Steigerung der Performance habe ich das DB-Schema um eine Geo-Spalte “PointOnSurface” erweitert, die durch einen Trigger “gefüttert” wird. Jedesmal, wenn sich ein Polygon ändert, wird PointOnSurface=ST_PointOnSurface(way) automatisch neu berechnet und steht mir dann sehr günstig zur Verfügung.

Wem sagst du das? :wink: Kennst du meinen Boundaries-Karte? (url im Subjekt). Genau dafür - die Visualisierung verschachtelter Grenzen - hab ich das mit dem Tree ja gemacht. Ist nur ziemlich zäh was die Darstellung mit OpenLayers betrifft.

Wenn du das einbauen möchtest, gerne. Ich stell dir natürlich auch alle Sourcen zur Verfügung, ist aber alles in Java und zumindest als Vorlage geeignet.
Was bei mit fehlt, ist einen automatische Analyse der Verschachtelung was Fehler betrifft, das geht bei mir nur visuell.

Gruss
walter

  4148168 | DEU     | Giebringhausenr (9)

Das sieht doch sehr nach einem Schreibfehler aus.

Zwischenbemerkung:
In Polen wird admin_level 10 abgeschafft, warum auch immer.

Die wollten ja auch über 30000 Admin-Grenzen mit AL=7.5 einführen. Deshalb hab ich die von einiger Zeit aus der Auswertung genommen.
Nur kann ich jetzt keine einzige davon in der DB finden - sollte die Vernunft doch gesiegt haben? Oder das kommt das noch.

Schau’n wir mal

Gruss
walter

Moin,

hier die Ergebnisse der letzten Auswertung:

Ausgewertet wurden DEU, ROU, RWA und der P-Block

DEU: +9, -2
PHL: +1
POL: +277
RWA: +1, -1

Polen ist anscheinend wieder sauber (AL 7.5-frei).

Gruss
Walter

@chris: ich sehe in Polen eigentlich keine großen Änderungen, was AL10 betrifft. Es sind sogar 5 mehr als vor einem Monat. Was geht denn da genau ab?


Country:	POL				Country:	Pol
Relation:	49715				Relation:	49715
Timestamp:	2014-10-01 06:26:36.964614	Timestamp:	2014-11-01 05:11:45.549843

AL	 count					al  | count
--------------					----+-------
 2	     1					 2  |     1
 4	    16					 4  |    16
 6	   378					 6  |   378
 7	  2477					 7  |  2477
 8	  4732					 8  |  4968
 9	   531					 9  |   566
10	    92					10  |    97
11	   642					11  |   643
12	    23					12  |    23
13	     1 					13  |     1
	------					     ------
	  8893					       9170

Ich hatte es auf der mkgmap Mailinglist aufgeschnappt:

Mehr weiß ich nicht.

Fixed.

Naja, die versprechen viel und dann passiert eh nix.

Ich nehme die AL so wie sie kommen. Das Konzept, das wir bei uns durchziehen, ist sowieso bei vielen Ländern anders (*). Daher steht in meiner Wiki-Liste ja auch: Level1 für AL2, Level2 für unser AL4 und Level3 für unser AL6, das ist aber durchaus unterschiedlich.

Nur bei “krummen” AL spiele ich nicht mit.

Gruss
walter

*) Falls es überhaupt eines dort gibt. Wenn ich mir z.B. Portugal ansehe, packt mich das kalte Grauen.

  4151246 | DEU     | Grenze Ortsteil Lühnde (9)

Das muss sich jemand anschauen. Da hat jemand offenbar noch nicht ganz verstanden wie Grenzen funktionieren.

Mit JOSM ist es immer eine Qual die fragliche Gegend auf der Karte zu finden (Deutschland ist groß und meine Geographiekenntnisse sind jetzt nicht so gut, dass ich jedes Dorf auf der Karte verorten könnte). Jetzt im Moment ist es noch schwerer, da ich nicht zuhause bin und nur einen Laptop habe und das mit dem Touchpad fürchterlich ist.

mach ich
done und Kollegen angeschrieben.

Da hat jemand offenbar noch nicht ganz verstanden wie Josm funktioniert: :wink:

  • Datei → Objekt herunterladen → Objekttyp=Relation
  • Relation eingeben
  • Häkchen bei Relationselemente herunterladen
  • ab damit.

Vor dem Bearbeiten Nachladen nicht vergessen!

Gruss
walter

Moin,

hier die Ergebnisse der letzten Auswertung:

Ausgewertet wurden DEU, BRA, CHE, CHN, GBR, HUN und IRL

DEU: +14
BRA: +142, -1
CHE: -1
CHN: +10, -5
GBR: +48, -2
HUN: -3
IRL: +1004 AL10 Wenn das kein Import ist?

Gruss
Walter

ps: die nächtliche Komplettauswertung klemmt noch ein wenig, wird aber immer besser.

Moin,

Ich habe in den letzten Tagen die Auswertung umgestellt und kann jetzt jede Nacht alle Administrativen Boundaries der Welt auswerten (sind ja “nur” ca 270.000 ;))
Aus diesem Grund ändern sich Name und Inhalt der in meinem Wiki abgespeicherten Reports:

hier stehen die Ergebnisse der letzten Auswertung:

DEU: +13, -1
BRA: +2
CHN: +6
DZA: +9
GBR: +24
HUN: +3
IND: +2
IRL: +69
NIC: +1
POL: +13
RUS: +61
TUN: +1
USA: +5

Ein paar Kleinigkeiten sind noch nicht ok; so fehlen bei vielen “Missing Boundaries” noch die Länderschlüssel. Das liegt daran, daß es nicht gerade einfach ist, von einer gelöschten Grenze noch ehemalige Daten zu bekommen. Das dürfte aber in einigen Tagen geklärt sein, da die Auswertung ein “selbstlernendes System” ist und sich eine eigene History aufbaut. Ich werde versuchen, die fehlenden Codes gleich händisch nachzutragen :frowning:

Auch fehlt ab und zu der Name der Grenze; ich habe schon festgestellt, daß dann irgendwas mit der Grenze eh nicht ok ist - aber was? Einfach reinschauen und korrigieren.

Gruss
walter

Edit: Sorry, falscher Link

Moin,

hier stehen die Ergebnisse der letzten globalen Auswertung.

DEU: +3, -2
ARG: +14, -1
BGR: +2
CAN: +2
FRA: -1
GBR: +27, -1
IRL: +144
NLD: -2
JPN: +3
POL: -1
PRT: +21
RUS: +80
TUN: +1
TUR: +1, -4
UKR: +3
URY: +3
USA: +2

Das mit den unbekannten Ländercodes bei den “Missings” ist geklärt: solange noch ein Rest der Relation in OSM vorhanden ist, komme ich dran. Damit kann ich sogar zwischen “defekt” und “fehlend” unterscheiden - muß ich nur noch in den Report einbauen.

Und dann fehlt noch die Grafik, da zickt QGIS immer noch rum.

Gruss
walter

Moin,

hier stehen die Ergebnisse der letzten globalen Auswertung.

Ab heute hier nur noch die Verluste:

DEU: -2
BRA: -7
FRA: -2
GBR: -1
IRL: -2
ITA:-2
TWN: -3
USA: -1

unknown: -2

Die Grafik funzt wieder :slight_smile:

So erstelle ich übrigens die Grafik in QGIS automatisch durch einen Python-Batch:


from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtGui 
import processing, sys, time, psycopg2
import pprint

#Define our connection string
conn_string = "host='localhost' dbname='planet2' user='osm'"
 
# print the connection string we will use to connect
#print "Connecting to database\n	->%s" % (conn_string)
 
# get a connection, if a connect cannot be made an exception will be raised here
conn = psycopg2.connect(conn_string)
 
# conn.cursor will return a cursor object, you can use this cursor to perform queries
cursor = conn.cursor()
#print "Connected!\n"

# execute our Query
cursor.execute("select * from osmstate " +
		"where line like 'timestamp=%' " +
		"order by lfn desc limit 1")
 
# retrieve the records from the database
record = cursor.fetchone()
 
# print out the records using pretty print
#pprint.pprint(record)

ts = record[2][10:]
print ts

uri = QgsDataSourceURI()

uri.setConnection("localhost", "5432", "planet2", "osm", "")

uri.setDataSource("public", "planet_osm_polygon", "way", 
    "boundary='administrative' and osm_id<0 and admin_level = '2'","osm_id")
#print uri.uri()

pgLayer = QgsVectorLayer(uri.uri(), "Countries2", "postgres")

if not pgLayer.isValid():
  print "Layer countries failed to load!"
#  sys.exit(1)
  
pgRenderer = pgLayer.rendererV2()
#print "Type:", pgRenderer.type()

symbols = pgRenderer.symbols()
symbol = symbols[0]

symbol.setColor(QtGui.QColor.fromRgb(0,255,0))

#print renderer.dump()

#qgis.utils.iface.mapCanvas().refresh() 
#qgis.utils.iface.legendInterface().refreshLayerSymbology(pglayer)

QgsMapLayerRegistry.instance().addMapLayer(pgLayer)

clipLayer = QgsVectorLayer("/data/osm/qgis/shapes/coastline.shp", "Landuse", "ogr")

if not clipLayer.isValid():
  print "Clipping Layer failed to load!"
#  sys.exit(1)
  
clipRenderer = clipLayer.rendererV2()
clipRenderer.symbols()[0].setColor(QtGui.QColor.fromRgb(255,0,0))
QgsMapLayerRegistry.instance().addMapLayer(clipLayer)

processing.runalg('qgis:clip', pgLayer, clipLayer, "/tmp/missing_countries")

missingLayer = QgsVectorLayer("/tmp/missing_countries.shp", "Missing Countries", "ogr")
if not missingLayer.isValid():
  print "missingLayer failed to load!"

missingRenderer = missingLayer.rendererV2()
missingRenderer.symbols()[0].setColor(QtGui.QColor.fromRgb(0,240,0)) 
QgsMapLayerRegistry.instance().addMapLayer(missingLayer)

#mapLayers = QgsMapLayerRegistry.instance().mapLayers()
pgId = pgLayer.id();
print pgId

QgsMapLayerRegistry.instance().removeMapLayer(pgId)

################### MapComposer #####################

mapRenderer = iface.mapCanvas().mapRenderer()

layers = [missingLayer.id(),clipLayer.id()]
mapRenderer.setLayerSet(layers)

c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)

c.setPaperSize(148,90)
c.setPrintResolution(300)

# add map
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()
print w,h
composerMap = QgsComposerMap(c, x,y,w,h)
c.addItem(composerMap)

#output to image
dpi = c.printResolution()
dpmm = dpi / 25.4
width = int(dpmm * c.paperWidth())
height = int(dpmm * c.paperHeight())

BackgroundColor = QColor(0,0,255)

# create output image and initialize it
image = QImage(QSize(width, height), QImage.Format_ARGB32)
image.setDotsPerMeterX(dpmm * 1000)
image.setDotsPerMeterY(dpmm * 1000)
image.fill(BackgroundColor)

header = QgsComposerLabel(c)
header.setItemPosition(40,1)
header.setBackgroundEnabled(0)
newFont = QFont("Comic Sans MS", 18)
header.setFont(newFont)
header.setText("Missing Countries Map")
header.adjustSizeToText()
c.addItem(header)

header2 = QgsComposerLabel(c)
header2.setItemPosition(50,11)
header2.setBackgroundEnabled(0)
newFont2 = QFont("Comic Sans MS", 10)
header2.setFont(newFont2)
header2.setText("TS="+ts)
header2.adjustSizeToText()
c.addItem(header2)

footer = QgsComposerLabel(c)
footer.setItemPosition(124,87.5)
footer.setBackgroundEnabled(0)
newFont3 = QFont("Times Roman", 4)
footer.setFont(newFont3)
footer.setText(time.ctime())
footer.adjustSizeToText()
c.addItem(footer)

legend = QgsComposerLegend(c)
legend.model().setLayerSet(mapRenderer.layerSet())
legend.setItemPosition(5,65)
legend.setFrameEnabled(1)
newFont = QFont("Comic Sans MS", 6)
legend.setStyleFont(QgsComposerLegendStyle.Title, newFont)
legend.setStyleFont(QgsComposerLegendStyle.Subgroup, newFont)
legend.setStyleFont(QgsComposerLegendStyle.SymbolLabel, newFont)
legend.setStyleMargin(QgsComposerLegendStyle.Title,2)
legend.setTitle("Legend")
legend.setSymbolHeight(2)
legend.adjustBoxSize()
c.addItem(legend)

# render the composition
imagePainter = QPainter(image)
imagePainter.setRenderHint(QPainter.Antialiasing)
sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight())
targetArea = QRectF(0, 0, width, height)
c.render(imagePainter, targetArea, sourceArea)
imagePainter.end()
try:
   imageFile = "/data/osm/maven/DataServer/data/osm/forum/admin/Q_World_Gaps_"+ts+".png"
   print "saving to "+imageFile
   image.save(imageFile)
except:
    print "image error"

  • hole aktuellen Timestamp aus der DB
  • lade aktuelle Grenzen aus der DB (Layer Countries2)
  • lade Coastline als Shape (Layer Landuse)
  • clippe beide, sodass die Maritimen Grenzen entfernt werden (–> Layer Missing Countries)
  • erzeuge eine Grafik mit allem Drumherum

Laufzeit ca 1 Minute

Gruss
walter

Fixed. Jemand hatte ein Grenzsegment einfach gelöscht. Passiert recht häufig…

PS: Habe gestern doch tatsächlich meinen Changeset #10.000 verpasst zu feiern. Yippie

und dann bezieht er sich noch auf KeepRight :rage:

auch Yippie :wink:

Gruss
walter

Moin,

hier stehen die Ergebnisse der letzten globalen Auswertung.

Hier nur noch die Verluste:

DEU: -2
ARG: -1
AUT: -1
BRA: -4
CAN: -1
FRA: -1
GBR: -4
MAR: -2
PHL: -1
USA: -3
ZAF: -2
unknown: -4

Die AL2 sind weltweit ok.

Gruss
walter

Moin,

hier stehen die Ergebnisse der letzten globalen Auswertung.

Verluste:

DEU: -
ARG: -4
IRL: -2
NZL: -2
RUS: -4
USA: -2

Die AL2 sind weltweit ok.

Gruss
walter