Ejemplo n.º 1
0
    def run(self, osmosis, parser, mapping, db_schema, default_table_base_name,
            time):
        """
        @return if data loaded in data base
        """
        table_base_name = self.table_name or default_table_base_name
        if len(table_base_name) <= 63:  # 63 max postgres relation name
            table = table_base_name
        else:
            table = table_base_name[-(63 - 10):] + hashlib.md5(
                table_base_name).hexdigest()[-10:]

        osmosis.run(
            "CREATE TABLE IF NOT EXISTS meta (name character varying(255) NOT NULL, update integer, bbox character varying(1024) )"
        )

        self.data = False

        def setDataTrue():
            self.data = True

        osmosis.run0(
            "SELECT * FROM meta WHERE name='%s' AND update=%s" % (table, time),
            lambda res: setDataTrue())
        if not self.data:
            osmosis.logger.log(u"Load source into database")
            osmosis.run("DROP TABLE IF EXISTS %s" % table)
            if not self.create:
                header = parser.header()
                if header:
                    if header != True:
                        self.create = ",".join(
                            map(lambda c: "\"%s\" VARCHAR(65534)" % c[0:50],
                                header))
                else:
                    raise AssertionError("No table schema provided")
            osmosis.run(sql_schema % {"schema": db_schema})
            if self.create:
                osmosis.run("CREATE TABLE %s (%s)" % (table, self.create))
            parser.import_(table, self.srid, osmosis)
            osmosis.run("DELETE FROM meta WHERE name = '%s'" % table)
            osmosis.run("INSERT INTO meta VALUES ('%s', %s, NULL)" %
                        (table, time))
            osmosis.run0("COMMIT")
            osmosis.run0("BEGIN")
            parser.close()

        # Convert
        country_hash = osmosis.config.db_schema.split(
            '_')[-1][0:10] + hashlib.md5(
                osmosis.config.db_schema).hexdigest()[-4:]
        if len(
                default_table_base_name + '_' + country_hash
        ) <= 63 - 2 - 3:  # 63 max postgres relation name, 3 is index name prefix
            tableOfficial = default_table_base_name + '_' + country_hash + "_o"
        else:
            tableOfficial = (default_table_base_name + '_' + country_hash
                             )[-(63 - 2 - 3 - 4):] + '_o' + hashlib.md5(
                                 default_table_base_name).hexdigest()[-4:]

        self.data = False

        def setData(res):
            self.data = res

        osmosis.run0(
            "SELECT bbox FROM meta WHERE name='%s' AND bbox IS NOT NULL AND update IS NOT NULL AND update=%s"
            % (tableOfficial, time), lambda res: setData(res))
        if not self.data:
            self.pip = PointInPolygon.PointInPolygon(
                self.polygon_id) if self.srid and self.polygon_id else None
            osmosis.logger.log(u"Convert data to tags")
            osmosis.run(sql_schema % {"schema": db_schema})
            osmosis.run(sql00 % {"official": tableOfficial})
            giscurs = osmosis.gisconn.cursor(
                cursor_factory=psycopg2.extras.DictCursor)
            giscurs_getpoint = osmosis.gisconn.cursor(
                cursor_factory=psycopg2.extras.DictCursor)

            def insertOfficial(res):
                x = self.xFunction(res[0])
                y = self.yFunction(res[1])
                if (not self.pip or (x and y)) and self.where(res):
                    is_pip = False
                    if self.pip:
                        giscurs_getpoint.execute(
                            "SELECT ST_AsText(ST_Transform(ST_SetSRID(ST_MakePoint(%(x)s, %(y)s), %(SRID)s), 4326))"
                            % {
                                "x": x,
                                "y": y,
                                "SRID": self.srid
                            })
                        lonLat = self.osmosis.get_points(
                            giscurs_getpoint.fetchone()[0])[0]
                        lonLat = [float(lonLat["lon"]), float(lonLat["lat"])]
                        is_pip = self.pip.point_inside_polygon(
                            lonLat[0], lonLat[1])
                    if not self.pip or is_pip:
                        for k in res.iterkeys():
                            if res[k] != None and isinstance(
                                    res[k], basestring):
                                res[k] = ' '.join(res[k].split(
                                ))  # Strip and remove duplicate space
                        tags = mapping.generate.tagFactory(res)
                        tags[1].update(tags[0])
                        giscurs.execute(
                            sql02.replace("%(official)s", tableOfficial), {
                                "ref":
                                tags[1].get(mapping.osmRef)
                                if mapping.osmRef != "NULL" else None,
                                "tags":
                                tags[1],
                                "tags1":
                                tags[0],
                                "fields":
                                dict(
                                    zip(
                                        dict(res).keys(),
                                        map(lambda x: unicode(x),
                                            dict(res).values()))),
                                "lon":
                                lonLat[0] if is_pip else None,
                                "lat":
                                lonLat[1] if is_pip else None
                            })

            if isinstance(self.x, tuple):
                self.x = self.x[0]
            else:
                self.x = "\"%s\"" % self.x
            if isinstance(self.y, tuple):
                self.y = self.y[0]
            else:
                self.y = "\"%s\"" % self.y
            if self.uniq:
                l = ','.join(map(lambda v: '"%s"' % v, self.uniq))
                distinct = "DISTINCT ON (%s)" % l
                order_by = "ORDER BY %s" % l
            else:
                distinct = order_by = ""
            osmosis.run0(
                (sql01_ref if mapping.osmRef != "NULL" else sql01_geo) % {
                    "table": table,
                    "x": self.x,
                    "y": self.y,
                    "where": self.formatCSVSelect(),
                    "distinct": distinct,
                    "order_by": order_by
                }, insertOfficial)
            if self.srid:
                giscurs.execute(
                    "SELECT ST_AsText(ST_Envelope(ST_Extent(geom::geometry))::geography) FROM %s"
                    % tableOfficial)
                self.bbox = giscurs.fetchone()[0]
            else:
                self.bbox = None
            osmosis.run(sql03 % {"official": tableOfficial})

            giscurs_getpoint.close()
            giscurs.close()

            osmosis.run("DELETE FROM meta WHERE name='%s'" % tableOfficial)
            if self.bbox != None:
                osmosis.run("INSERT INTO meta VALUES ('%s', %s, '%s')" %
                            (tableOfficial, time, self.bbox))
            osmosis.run0("COMMIT")
            osmosis.run0("BEGIN")
        else:
            self.bbox = self.data[0]

        if not (self.srid and not self.bbox):  # Abort condition
            return tableOfficial
Ejemplo n.º 2
0
    def run(self, osmosis, parser, mapping, db_schema, default_table_base_name, time):
        """
        @return if data loaded in data base
        """
        table_base_name = self.table_name or default_table_base_name
        if len(table_base_name) <= 63: # 63 max postgres relation name
            table = table_base_name
        else:
            table = table_base_name[-(63-10):]+hexastablehash(table_base_name)[-10:]

        osmosis.run("CREATE UNLOGGED TABLE IF NOT EXISTS meta (name character varying(255) NOT NULL, update integer, bbox character varying(1024) )")

        self.data = False
        def setDataTrue():
            self.data = True
        osmosis.run0("SELECT * FROM meta WHERE name='{0}' AND update={1}".format(table, time), lambda res: setDataTrue())
        if not self.data:
            osmosis.logger.log(u"Load source into database")
            osmosis.run("DROP TABLE IF EXISTS {0}".format(table))
            if not self.create:
                header = parser.header()
                if header:
                    if header is not True:
                        self.create = ",".join(map(lambda c: "\"{0}\" VARCHAR(65534)".format(c[0:50]), header))
                else:
                    raise AssertionError("No table schema provided")
            osmosis.run(sql_schema.format(schema = db_schema))
            if self.create:
                osmosis.run("CREATE UNLOGGED TABLE {0} ({1})".format(table, self.create))
            parser.import_(table, self.srid, osmosis)
            osmosis.run("DELETE FROM meta WHERE name = '{0}'".format(table))
            osmosis.run("INSERT INTO meta VALUES ('{0}', {1}, NULL)".format(table, time))
            osmosis.run0("COMMIT")
            osmosis.run0("BEGIN")
            parser.close()

        # Convert
        country_hash = osmosis.config.db_schema.split('_')[-1][0:10] + hexastablehash(osmosis.config.db_schema)[-4:]
        if len(default_table_base_name + '_' + country_hash) <= 63-2-3: # 63 max postgres relation name, 3 is index name prefix
            tableOfficial = default_table_base_name + '_' + country_hash + "_o"
        else:
            tableOfficial = (default_table_base_name + '_' + country_hash)[-(63-2-3-4):] + '_o' + hexastablehash(default_table_base_name)[-4:]

        self.data = False
        def setData(res):
            self.data = res
        osmosis.run0("SELECT bbox FROM meta WHERE name='{0}' AND bbox IS NOT NULL AND update IS NOT NULL AND update={1}".format(tableOfficial, time), lambda res: setData(res))
        if not self.data:
            self.pip = PointInPolygon.PointInPolygon(self.polygon_id) if self.srid and self.polygon_id else None
            if self.pip:
                if Transformer:
                    transformer = Transformer.from_crs(self.srid, 4326, always_xy = True)
                else: # pyproj < 2.1
                    transformer = None
            osmosis.logger.log(u"Convert data to tags")
            osmosis.run(sql_schema.format(schema = db_schema))
            osmosis.run(sql00.format(official = tableOfficial))
            giscurs = osmosis.gisconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
            giscurs_getpoint = osmosis.gisconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
            mult_space = re.compile(r'\s+')
            def insertOfficial(res):
                if not self.where(res):
                    return
                res = self.map(res)
                x = self.xFunction(res['_x'])
                y = self.yFunction(res['_y'])
                if not self.pip or (x and y):
                    is_pip = False
                    if self.pip:
                        if transformer:
                            lonLat = transformer.transform(x, y)
                        else:
                            giscurs_getpoint.execute("SELECT ST_AsText(ST_Transform(ST_SetSRID(ST_MakePoint({x}, {y}), {srid}), 4326))".format(x=x, y=y, srid=self.srid))
                            lonLat = self.osmosis.get_points(giscurs_getpoint.fetchone()[0])[0]
                            lonLat = [float(lonLat["lon"]), float(lonLat["lat"])]
                        is_pip = self.pip.point_inside_polygon(lonLat[0], lonLat[1])
                    if not self.pip or is_pip:
                        for k in res.keys():
                            try:
                                res[k] = mult_space.sub(' ', res[k].strip()) # Strip and remove duplicate space
                            except AttributeError:
                                pass
                        tags = mapping.generate.tagFactory(res)
                        tags[1].update(tags[0])
                        giscurs.execute(sql02.format(official = tableOfficial), {
                            "ref": tags[1].get(mapping.osmRef) if mapping.osmRef != "NULL" else None,
                            "tags": tags[1],
                            "tags1": tags[0],
                            "fields": dict(zip(dict(res).keys(), map(lambda s: (s is None and None) or u'{0}'.format(s), dict(res).values()))),
                            "lon": lonLat[0] if is_pip else None, "lat": lonLat[1] if is_pip else None
                        })
            if isinstance(self.x, tuple):
                self.x = self.x[0]
            else:
                self.x = "\"{0}\"".format(self.x)
            if isinstance(self.y, tuple):
                self.y = self.y[0]
            else:
                self.y = "\"{0}\"".format(self.y)
            if self.uniq:
                l = ','.join(map(lambda v: '"{0}"'.format(v), self.uniq))
                distinct = "DISTINCT ON ({0})".format(l)
                order_by = "ORDER BY {0}".format(l)
            else:
                distinct = order_by = ""
            osmosis.run0((sql01_ref if mapping.osmRef != "NULL" else sql01_geo).format(table = table, x = self.x, y = self.y, where = self.formatCSVSelect(), distinct = distinct, order_by = order_by), insertOfficial)
            osmosis.run(sql02b.format(official = tableOfficial))
            if self.srid:
                giscurs.execute("SELECT ST_AsText(ST_Envelope(ST_Extent(geom::geometry))::geography) FROM {0}".format(tableOfficial))
                self.bbox = giscurs.fetchone()[0]
            else:
                self.bbox = None
            osmosis.run(sql03a.format(official = tableOfficial))
            osmosis.run(sql03b.format(official = tableOfficial))

            giscurs_getpoint.close()
            giscurs.close()

            osmosis.run("DELETE FROM meta WHERE name='{0}'".format(tableOfficial))
            if self.bbox is not None:
                osmosis.run("INSERT INTO meta VALUES ('{0}', {1}, '{2}')".format(tableOfficial, time, self.bbox))
            osmosis.run0("COMMIT")
            osmosis.run0("BEGIN")
        else:
            self.bbox = self.data[0]

        if not(self.srid and not self.bbox): # Abort condition
            return tableOfficial