Ejemplo n.º 1
0
    def push_flood_forecast_event_plpy(self, flood_forecast_events):
        import plpy

        # Filter only the needed column
        flood_events = [
            {
                'flood_map_id': v['flood_map_id'],
                'acquisition_date': v['acquisition_date'].isoformat(),
                'forecast_date': v['forecast_date'].isoformat(),
                'source': v['source'],
                'notes': v['notes'],
                'link': v['link'],
                'trigger_status': v['trigger_status_candidate'],
                # Progress 1 means, impact level has not been calculated
                'progress': GloFASForecast.PROGRESS_IN_PROGRESS
            } for v in flood_forecast_events
        ]
        json_string = json.dumps(flood_events)

        # The process needs to be idempotent, so delete matching forecast first
        for event in flood_events:
            plan = plpy.prepare(self.plpy_flood_event_delete_filter,
                                ["int", "timestamp", "timestamp", "varchar"])
            plpy.execute(plan, [
                event['flood_map_id'], event['acquisition_date'],
                event['forecast_date'], event['source']
            ])

        # We bulk insert the events
        plan = plpy.prepare(self.plpy_flood_event_insert_query, ["text"])
        result = plpy.execute(plan, [json_string])
        return result
Ejemplo n.º 2
0
    def get_plan(self, sql, types):
        """Prepare the plan and cache it."""

        t = (sql, tuple(types))
        if t in self.plan_map:
            pc = self.plan_map[t]
            # put to the end
            self.plan_list.remove(pc)
            self.plan_list.append(pc)
            return pc.plan

        # prepare new plan
        plan = plpy.prepare(sql, types)

        # add to cache
        pc = CachedPlan(t, plan)
        self.plan_list.append(pc)
        self.plan_map[t] = pc

        # remove plans if too much
        while len(self.plan_map) > self.maxplans:
            # this is ugly workaround for pylint
            drop = self.plan_list.pop()
            del self.plan_map[getattr(drop, 'key')]

        return plan
Ejemplo n.º 3
0
    def get_plan(self, sql, types):
        """Prepare the plan and cache it."""

        t = (sql, tuple(types))
        if t in self.plan_map:
            pc = self.plan_map[t]
            # put to the end
            self.plan_list.remove(pc)
            self.plan_list.append(pc)
            return pc.plan

        # prepare new plan
        plan = plpy.prepare(sql, types)

        # add to cache
        pc = CachedPlan(t, plan)
        self.plan_list.append(pc)
        self.plan_map[t] = pc

        # remove plans if too much
        while len(self.plan_map) > self.maxplans:
            pc = self.plan_list.pop()
            del self.plan_map[pc.key]

        return plan
Ejemplo n.º 4
0
 def __init__(self, sql):
     qb = QueryBuilder(sql, None)
     p_sql = qb.get_sql(PARAM_PLPY)
     p_types =  qb._arg_type_list
     self.plan = plpy.prepare(p_sql, p_types)
     self.arg_map = qb._arg_value_list
     self.sql = sql
Ejemplo n.º 5
0
    def get_plan(self, sql, types):
        """Prepare the plan and cache it."""

        t = (sql, tuple(types))
        if t in self.plan_map:
            pc = self.plan_map[t]
            # put to the end
            self.plan_list.remove(pc)
            self.plan_list.append(pc)
            return pc.plan

        # prepare new plan
        plan = plpy.prepare(sql, types)

        # add to cache
        pc = CachedPlan(t, plan)
        self.plan_list.append(pc)
        self.plan_map[t] = pc

        # remove plans if too much
        while len(self.plan_map) > self.maxplans:
            pc = self.plan_list.pop()
            del self.plan_map[pc.key]

        return plan
Ejemplo n.º 6
0
def _plan_batch(insert_sql, column_types, batch_size):
    index = 1  # PostgreSQL's place holder begins from 1

    # append value list (...), (...), ... at the end of insert_sql
    batch_isnert_sql = [insert_sql]
    first = True
    for i in range(batch_size):
        if first:
            first = False
        else:
            batch_isnert_sql.append(", ")

        # ($1::column_type, $2::column_type, ...)
        batch_isnert_sql.append("(")
        value_first = True
        for column_type in column_types:
            if value_first:
                value_first = False
            else:
                batch_isnert_sql.append(", ")

            batch_isnert_sql.append("$%s::%s" % (index, column_type))
            index += 1
        batch_isnert_sql.append(")")

    return plpy.prepare(''.join(batch_isnert_sql), column_types * batch_size)
Ejemplo n.º 7
0
 def __init__(self, sql):
     qb = QueryBuilder(sql, None)
     p_sql = qb.get_sql(PARAM_PLPY)
     p_types = qb._arg_type_list
     self.plan = plpy.prepare(p_sql, p_types)
     self.arg_map = qb._arg_value_list
     self.sql = sql
Ejemplo n.º 8
0
    def execute(self, operation, parameters=None):
        if self._is_closed():
            raise Error()

        self.connection._ensure_transaction()

        parameters = parameters or []

        placeholders = []
        types = []
        values = []
        i = 0
        for param in parameters:
            if param is None:
                # Directly put "None" as "NULL" in the sql
                # as it's not possible to get the type
                placeholders.append('NULL')
            else:
                i += 1
                placeholders.append("$%d" % i)
                types.append(self.py_param_to_pg_type(param))
                if types[-1] == 'bytea' and hasattr(param, 'tobytes'):
                    values.append(param.tobytes())
                else:
                    values.append(param)
        query = operation % tuple(placeholders)
        try:
            plan = plpy.prepare(query, types)
            res = plpy.execute(plan, values)
        except plpy.SPIError as e:
            raise Error(e)

        self._execute_result = None
        self.rownumber = None
        self.description = None
        self.rowcount = -1

        if res.status() in [self._SPI_OK_SELECT, self._SPI_OK_INSERT_RETURNING,
                self._SPI_OK_DELETE_RETURNING, self._SPI_OK_UPDATE_RETURNING]:
            if 'colnames' in res.__class__.__dict__:
                # Use colnames to get the order of the variables in the query
                self._execute_result = [tuple([row[col] for col in res.colnames()]) for row in res]
            else:
                self._execute_result = [tuple([row[col] for col in row]) for row in res]
            self.rownumber = 0
            if 'colnames' in res.__class__.__dict__:
                # PG 9.2+: use .colnames() and .coltypes() methods
                self.description = [(name, get_type_obj(typeoid), None, None, None, None, None) for name, typeoid in zip(res.colnames(), res.coltypes())]
            elif len(res) > 0:
                # else get at least the column names from the row keys
                self.description = [(name, None, None, None, None, None, None) for name in res[0].keys()]
            else:
                # else we know nothing
                self.description = [(None, None, None, None, None, None, None)]

        if res.status() == self._SPI_OK_UTILITY:
            self.rowcount = -1
        else:
            self.rowcount = res.nrows()
Ejemplo n.º 9
0
def plpy_execute(query, types, values):
    assert query.count('%s') == len(types)
    assert len(types) == len(values)

    for i in range(len(values)):
        query = query.replace('%s', '$' + str(i + 1), 1)

    plan = plpy.prepare(query, types)
    return plpy.execute(plan, values)
Ejemplo n.º 10
0
def hba_heuristic(source, target, tablename='vertex', col_geom='geom', col_id='id'):
  if heuristic_plan == -1:
    global heuristic_plan
    heuristic_plan = plpy.prepare('select st_distance(a.' + col_geom + ', b.' + col_geom + ') as cost from ' + tablename + ' as a, ' + tablename + ' as b where a.' + col_id + ' = $2 and b.' + col_id + ' = $3', ['text', 'integer', 'integer', 'text', 'text'])
  try:
    return plpy.execute(heuristic_plan, [col_geom, source, target, tablename, col_id], 1)[0]['cost']
  except:
    plpy.info("No heuristic distance. This is a bug, probably.")
    return float('inf')
Ejemplo n.º 11
0
def get_type_obj(typeoid):
    """Return the type object (STRING, NUMBER, etc.) that corresponds
    to the given type OID."""
    if not _typoid_typeobjs:
        for row in plpy.execute(plpy.prepare("SELECT oid, typname, typcategory FROM pg_type")):
            if row['typcategory'] in _typcategory_typeobjs:
                _typoid_typeobjs[int(row['oid'])] = _typcategory_typeobjs[row['typcategory']]
            elif row['typname'] in _typname_typeobjs:
                _typoid_typeobjs[int(row['oid'])] = _typname_typeobjs[row['typname']]

    return _typoid_typeobjs.get(typeoid)
Ejemplo n.º 12
0
def country_to_iso3(country):
    """ Convert country to its iso3 code """
    try:
        country_plan = plpy.prepare("SELECT adm0_a3 as iso3 FROM admin0_synonyms WHERE lower(regexp_replace($1, " \
                                    "'[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = name_; ", ['text'])
        country_result = plpy.execute(country_plan, [country], 1)
        if country_result:
            return country_result[0]['iso3']
        else:
            return None
    except BaseException as e:
        plpy.warning("Can't get the iso3 code from {0}: {1}".format(country, e))
        return None
Ejemplo n.º 13
0
    def execute(self, operation, parameters=None):
        if self._is_closed():
            raise Error()

        self.connection._ensure_transaction()

        parameters = parameters or []

        placeholders = []
        types = []
        values = []
        for i, param in enumerate(parameters):
            placeholders.append("$%d" % (i + 1))
            types.append(self.py_param_to_pg_type(param))
            values.append(param)
        if len(placeholders) == 1:
            query = operation % placeholders[0]
        else:
            query = operation % placeholders
        try:
            plan = plpy.prepare(query, types)
            res = plpy.execute(plan, values)
        except plpy.SPIError as e:
            raise Error(e)

        self._execute_result = None
        self.rownumber = None
        self.description = None
        self.rowcount = -1

        if res.status() == self._SPI_OK_SELECT:
            self._execute_result = [[row[col] for col in row] for row in res]
            self.rownumber = 0
            if 'colnames' in res.__class__.__dict__:
                # PG 9.2+: use .colnames() and .coltypes() methods
                self.description = [
                    (name, get_type_obj(typeoid), None, None, None, None, None)
                    for name, typeoid in zip(res.colnames(), res.coltypes())
                ]
            elif len(res) > 0:
                # else get at least the column names from the row keys
                self.description = [(name, None, None, None, None, None, None)
                                    for name in res[0].keys()]
            else:
                # else we know nothing
                self.description = [(None, None, None, None, None, None, None)]

        if res.status() == self._SPI_OK_UTILITY:
            self.rowcount = -1
        else:
            self.rowcount = res.nrows()
Ejemplo n.º 14
0
def get_type_obj(typeoid):
    """Return the type object (STRING, NUMBER, etc.) that corresponds
    to the given type OID."""
    if not _typoid_typeobjs:
        for row in plpy.execute(
                plpy.prepare("SELECT oid, typname, typcategory FROM pg_type")):
            if row['typcategory'] in _typcategory_typeobjs:
                _typoid_typeobjs[int(
                    row['oid'])] = _typcategory_typeobjs[row['typcategory']]
            elif row['typname'] in _typname_typeobjs:
                _typoid_typeobjs[int(
                    row['oid'])] = _typname_typeobjs[row['typname']]

    return _typoid_typeobjs.get(typeoid)
Ejemplo n.º 15
0
def country_to_iso3(country):
    """ Convert country to its iso3 code """
    try:
        country_plan = plpy.prepare("SELECT adm0_a3 as iso3 FROM admin0_synonyms WHERE lower(regexp_replace($1, " \
                                    "'[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = name_; ", ['text'])
        country_result = plpy.execute(country_plan, [country], 1)
        if country_result:
            return country_result[0]['iso3']
        else:
            return None
    except BaseException as e:
        plpy.warning("Can't get the iso3 code from {0}: {1}".format(
            country, e))
        return None
Ejemplo n.º 16
0
    def find_flood_map_plpy(self, station_id, return_period_min, return_period_max):
        import plpy

        plan = plpy.prepare(self.plpy_query_flood_map_filter,
                            ["int", "int", "int"])
        result = plpy.execute(plan, [station_id, return_period_min,
                                     return_period_max])

        if len(result) == 0:
            # We didn't found any flood map
            return None

        # We found the flood map
        row = result[0]
        return row['id']
Ejemplo n.º 17
0
    def find_previous_flood_forecast_plpy(
            self, forecast_date, maximum_acquisition_date, source):
        import plpy

        plan = plpy.prepare(self.plpy_query_flood_map_filter,
                            ["timestamp", "timestamp", "varchar"])
        result = plpy.execute(
            plan, [maximum_acquisition_date.isoformat(), forecast_date.isoformat(), source])

        if len(result) == 0:
            # We didn't found any flood map
            return None

        # We found the flood map
        row = result[0]
        return row
Ejemplo n.º 18
0
    def execute(self, operation, parameters=None):
        if self._is_closed():
            raise Error()

        self.connection._ensure_transaction()

        parameters = parameters or []

        placeholders = []
        types = []
        values = []
        for i, param in enumerate(parameters):
            placeholders.append("$%d" % (i + 1))
            types.append(self.py_param_to_pg_type(param))
            values.append(param)
        if len(placeholders) == 1:
            query = operation % placeholders[0]
        else:
            query = operation % placeholders
        try:
            plan = plpy.prepare(query, types)
            res = plpy.execute(plan, values)
        except plpy.SPIError as e:
            raise Error(e)

        self._execute_result = None
        self.rownumber = None
        self.description = None
        self.rowcount = -1

        if res.status() == self._SPI_OK_SELECT:
            self._execute_result = [[row[col] for col in row] for row in res]
            self.rownumber = 0
            if 'colnames' in res.__class__.__dict__:
                # PG 9.2+: use .colnames() and .coltypes() methods
                self.description = [(name, get_type_obj(typeoid), None, None, None, None, None) for name, typeoid in zip(res.colnames(), res.coltypes())]
            elif len(res) > 0:
                # else get at least the column names from the row keys
                self.description = [(name, None, None, None, None, None, None) for name in res[0].keys()]
            else:
                # else we know nothing
                self.description = [(None, None, None, None, None, None, None)]

        if res.status() == self._SPI_OK_UTILITY:
            self.rowcount = -1
        else:
            self.rowcount = res.nrows()
Ejemplo n.º 19
0
def hba_astar(source, target, ol, cl, cl2, cat, d, p, tablename='routing', col_geom='geom', col_edge='id', col_cost='cost', col_revc='reverse_cost', col_source='source', col_target='target', vertex_tablename='vertex', col_cat='category', col_vertex_geom='geom', col_name='name', col_rule='rule'):
  #If we don't have open candidates...
  if len(ol) == 0:
    return 0
 
  if len(ol) > 0:
    #x <- node with smallest f-value
    x = hba_bestNext(ol)

    #We move through the next best option:
    cl.append(x)
    del ol[x]

    #Have we just found the middle point?
    if (x == target or x in cl2):
      try:
        last_id = int(p[x][1]['id'])
      except:
        last_id = -1
      global central_node_plan

      if "source" in col_source:
        check_x = plpy.execute(central_node_plan, [x, last_id])
      else: 
        check_x = plpy.execute(central_node_plan, [last_id, x])

      for checking in check_x:
        return x

    #Next candidates
    # If we are in the initialization buffer, use hba_adj_initialization
    if distance_plan == -1:
        global distance_plan
        distance_plan = plpy.prepare('\n\
            ' + 'SELECT min(st_distance_sphere(v1.geom, v2.geom)) as dist from vertex v1, vertex v2 where v1.id = $1 and (v2.id = $2 or v2.id = $3)',['Integer', 'Integer', 'Integer'])
    distance =plpy.execute(distance_plan, [x, source, target], 1)[0]["dist"]
    adj = hba_adj(cat, x, target, p,tablename, col_geom, col_edge, col_cost, col_source, col_target, col_revc, col_cat, col_name, col_rule)

    #Forever alone
    if adj is None:
      plpy.error("This vertex is alone")

    #For each candidate
    hba_process_y(adj, p, cat, d, ol, cl, x, target, vertex_tablename, col_vertex_geom, col_edge, [],  distance)
  
  #Return false, we still have to loop more
  return 0
Ejemplo n.º 20
0
def hba_astar(source, target, ol, cl, cl2, cat, d, p, tablename='routing', col_geom='geom', col_edge='id', col_cost='cost', col_revc='reverse_cost', col_source='source', col_target='target', vertex_tablename='vertex', col_cat='category', col_vertex_geom='geom', col_name='name', col_rule='rule'):
  #If we don't have open candidates...
  if len(ol) == 0:
    return 0
 
  if len(ol) > 0:
    #x <- node with smallest f-value
    x = hba_bestNext(ol)

    #We move through the next best option:
    cl.append(x)
    del ol[x]

    #Have we just found the middle point?
    if (x == target or x in cl2):
      return x

    #Next candidates
    # If we are in the initialization buffer, use hba_adj_initialization
    if distance_plan == -1:
        global distance_plan
        distance_plan = plpy.prepare('\n\
            ' + 'SELECT st_distance_sphere(v1.geom, v2.geom) as dist from vertex v1, vertex v2 where v1.id = $1 and v2.id = $2',
        ['Integer', 'Integer'])
    distance =plpy.execute(distance_plan, [source, x])[0]["dist"]
    plpy.info("Distance from origin=" + str(distance)) 
    if (distance <= distance_buffer):
      plpy.info("Using hba_adj_buffer")
      adj = hba_adj_buffer(x, target, p,tablename, col_geom, col_edge, col_cost, col_source, col_target, col_revc, col_cat, col_name, col_rule)
    else:
      plpy.info("Using hba_adj")
      adj = hba_adj(cat, x, target, p,tablename, col_geom, col_edge, col_cost, col_source, col_target, col_revc, col_cat, col_name, col_rule)
    #plpy.info("Obtained adjacents for node " + str(x) + " with category cat >= " + str(cat) + ". " + str(adj.nrows()) + " nodes.")

    #Forever alone
    if adj is None:
      plpy.error("This vertex is alone")

    #For each candidate
    hba_process_y(adj, p, cat, d, ol, cl, x, target, vertex_tablename, col_vertex_geom, col_edge, [],  distance)
  
  #Return false, we still have to loop more
  return 0
Ejemplo n.º 21
0
def hba_heuristic(source,
                  target,
                  tablename='vertex',
                  col_geom='geom',
                  col_id='id'):
    if heuristic_plan == -1:
        global heuristic_plan
        heuristic_plan = plpy.prepare(
            'select st_distance(a.' + col_geom + ', b.' + col_geom +
            ') as cost from ' + tablename + ' as a, ' + tablename +
            ' as b where a.' + col_id + ' = $2 and b.' + col_id + ' = $3',
            ['text', 'integer', 'integer', 'text', 'text'])
    try:
        return plpy.execute(heuristic_plan,
                            [col_geom, source, target, tablename, col_id],
                            1)[0]['cost']
    except:
        plpy.info("No heuristic distance. This is a bug, probably.")
        return float('inf')
Ejemplo n.º 22
0
def _transform(obj, type_, func_name, func_sign, params):
    ''' Transform obj, whose type is type_, using func_name, func_sign and params.
    '''
    if func_name not in func_names:
        plpy.error('function {} is unknown'.format(func_name))
    func_name = func_names[func_name]
    if isinstance(params, basestring):  # NOQA
        params = json.loads(params)
    args = [params[p] for p in func_sign if p != '_time']
    args_str, args_val = args_to_array_string(args)
    q = 'select {}(\'{}\'::{}{}) r'.format(func_name, obj, type_, args_str)
    plpy.debug(q, args_val)
    plan = plpy.prepare(q, ['numeric'] * len(args_val))
    rv = plpy.execute(plan, args_val)
    if len(rv) != 1:
        plpy.error('unexpected number of rows ({}) returned from {}'.format(len(rv), q))
    result = rv[0].get('r')
    if result is None:
        plpy.error('unexpected value None returned from {}'.format(q))
    return result
Ejemplo n.º 23
0
def _plan_batch(insert_sql, values_sql_format, column_types, batch_size):
    # format string 'values ($1, $2), ($3, $4) ...'
    values_sql = (", ".join([values_sql_format] * batch_size)).format(*range(1, batch_size * len(column_types) + 1))
    batch_insert_sql = insert_sql + values_sql
    return plpy.prepare(batch_insert_sql, column_types * batch_size)
Ejemplo n.º 24
0
def hba_astar(source,
              target,
              ol,
              cl,
              cl2,
              cat,
              d,
              p,
              tablename='routing',
              col_geom='geom',
              col_edge='id',
              col_cost='cost',
              col_revc='reverse_cost',
              col_source='source',
              col_target='target',
              vertex_tablename='vertex',
              col_cat='category',
              col_vertex_geom='geom',
              col_name='name',
              col_rule='rule'):
    #If we don't have open candidates...
    if len(ol) == 0:
        return 0

    if len(ol) > 0:
        #x <- node with smallest f-value
        x = hba_bestNext(ol)

        #We move through the next best option:
        cl.append(x)
        del ol[x]

        #Have we just found the middle point?
        if (x == target or x in cl2):
            try:
                last_id = int(p[x][1]['id'])
            except:
                last_id = -1
            global central_node_plan

            if "source" in col_source:
                check_x = plpy.execute(central_node_plan, [x, last_id])
            else:
                check_x = plpy.execute(central_node_plan, [last_id, x])

            for checking in check_x:
                return x

        #Next candidates
        # If we are in the initialization buffer, use hba_adj_initialization
        if distance_plan == -1:
            global distance_plan
            distance_plan = plpy.prepare(
                '\n\
            ' + 'SELECT min(st_distance_sphere(v1.geom, v2.geom)) as dist from vertex v1, vertex v2 where v1.id = $1 and (v2.id = $2 or v2.id = $3)',
                ['Integer', 'Integer', 'Integer'])
        distance = plpy.execute(distance_plan, [x, source, target],
                                1)[0]["dist"]
        adj = hba_adj(cat, x, target, p, tablename, col_geom, col_edge,
                      col_cost, col_source, col_target, col_revc, col_cat,
                      col_name, col_rule)

        #Forever alone
        if adj is None:
            plpy.error("This vertex is alone")

        #For each candidate
        hba_process_y(adj, p, cat, d, ol, cl, x, target, vertex_tablename,
                      col_vertex_geom, col_edge, [], distance)

    #Return false, we still have to loop more
    return 0
Ejemplo n.º 25
0
def hba_star_pl(source,
                target,
                tablename='routing',
                col_edge='id',
                col_cost='cost',
                col_revc='reverse_cost',
                col_rule='rule',
                col_source='source',
                col_target='target',
                col_geom='the_geom',
                col_name='name',
                col_cat='category',
                vertex_tablename='vertex',
                col_vertex_geom='geom'):

    #Closed Lists (backward and forward)
    clf = []
    clb = []

    #Open Lists (backward and forward)
    #Candidate nodes from which we want to continue calculating
    #Every node (key) contains (value) its estimated (heuristic) cost till the target
    olf = {}
    olb = {}

    #Total cost (backward and forward)
    #For every node, globally, its lowest cost from source/target
    d = {}
    d[target] = 0
    d[source] = 0

    #Predecessor array (backward and forward)
    #For every node, which is its previous node (related to d[])
    ps = {}
    pt = {}

    #Current category of search (backward and forward)
    catf = [10]
    catb = [10]

    #Initial values
    olf[source] = d[source] + hba_heuristic(source, target, vertex_tablename,
                                            col_vertex_geom, col_edge)
    olb[target] = d[target] + hba_heuristic(target, source, vertex_tablename,
                                            col_vertex_geom, col_edge)

    global adj_plan
    global adj_plan_rev
    global central_node_plan

    adj_plan_rev = plpy.prepare(
        'select a.*, ' + 'CASE WHEN a.name = $4 AND a.category <= 3 THEN \n\
		(a.length + st_distance_sphere(st_startpoint(a.geom), b.geom)) * (a.category + 1) \n\
	WHEN a.name = b.name THEN \n\
                a.length + st_distance_sphere(st_startpoint(a.geom), b.geom) \n\
	ELSE \n\
		(a.length + st_distance_sphere(st_startpoint(a.geom), b.geom)) * ' +
        str(heuristic_constant) + ' * (a.category + 1) \n\
	END as heuristic \n\
	from ((select  \n\
        ' + col_geom + ' as geom, \n\
        ' + col_edge + ' as id, \n\
        ' + col_cost + ' as cost,\n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' +
        col_geom + ')) as length,\n\
        ' + col_target + ' as source, \n\
        ' + col_source + ' as target, \n\
        ' + col_cat + ' as category, \n\
        ' + col_name + ' as name from ' + tablename + '\n\
        ) union all (select  \n\
        st_reverse(' + col_geom + ') as geom, \n\
        ' + col_edge + ' as id, \n\
        ' + col_revc + ' as cost, \n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' +
        col_geom + ')) as length,\n\
        ' + col_source + ' as source,\n\
        ' + col_target + ' as target, \n\
        ' + col_cat + ' as category, \n\
        ' + col_name + ' as name from ' + tablename + ' )\n\
        ) a, (select st_startpoint(' + col_geom + ')  as geom from ' +
        tablename + ' where ' + col_source + ' = $3 or ' + col_target +
        ' = $3 limit 1) b \n\
                where source = $1 and category >= 0\n\
                and cost <> \'Infinity\''

        #Turn restrictions:
        + 'and ' + col_edge + ' not in (SELECT ' + col_edge + ' from ' +
        tablename + ' r where r.' + col_rule + ' = $2)',
        ['Integer', 'Integer', 'Integer', 'text', 'Integer'])

    adj_plan = plpy.prepare(
        '\n\
    select a.*,' + 'CASE WHEN a.name = $4 AND a.category <= 3 THEN \n\
                (a.length + st_distance_sphere(st_startpoint(a.geom), b.geom))  * (a.category + 1) \n\
        WHEN a.name = b.name THEN \n\
                a.length + st_distance_sphere(st_startpoint(a.geom), b.geom) \n\
        ELSE \n\
                (a.length + st_distance_sphere(st_startpoint(a.geom), b.geom)) * '
        + str(heuristic_constant) + ' * (a.category + 1) \n\
        END as heuristic \n\
        from ((select  \n\
	st_reverse(' + col_geom + ') as geom, \n\
	' + col_edge + ' as id, \n\
	' + col_revc + ' as cost,\n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' +
        col_geom + ')) as length,\n\
	' + col_target + ' as source, \n\
	' + col_source + ' as target, \n\
	' + col_cat + ' as category, \n\
	' + col_name + ' as name from ' + tablename + '\n\
	) union all (select  \n\
	' + col_geom + ' as geom, \n\
	' + col_edge + ' as id, \n\
	' + col_cost + ' as cost, \n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' +
        col_geom + ')) as length,\n\
	' + col_source + ' as source,\n\
	' + col_target + ' as target, \n\
	' + col_cat + ' as category, \n\
	' + col_name + ' as name from ' + tablename + ' )\n\
	) a, (select st_startpoint(' + col_geom + ')  as geom  from ' + tablename +
        ' where ' + col_source + ' = $3 or ' + col_target +
        ' = $3 limit 1) b \n\
		where source = $1 and category >= 0\n\
		and cost <> \'Infinity\''

        #Turn restrictions:
        + 'and ' + col_edge + ' not in (SELECT ' + col_rule + ' from ' +
        tablename + ' r where r.' + col_edge + ' = $2 and ' + col_rule +
        ' is not null)',
        ['Integer', 'Integer', 'Integer', 'text', 'Integer'])

    central_node_plan = plpy.prepare(
        'SELECT 1 WHERE NOT EXISTS(SELECT 1 FROM ' + tablename + ' WHERE ' +
        col_edge + ' = $2 and ' + col_rule + ' = $1)', ['Integer', 'Integer'])

    #Star two-sided A* search

    m = -1
    m1 = 0
    m2 = 0

    #We try A* step by step until the two paths collided
    while not m1 and not m2 and (len(olf) > 0 and len(olb) > 0):
        m1 = hba_astar(source, target, olf, clf, clb, catf, d, ps, tablename,
                       col_geom, col_edge, col_cost, col_revc, col_source,
                       col_target, vertex_tablename, col_cat, col_vertex_geom,
                       col_name, col_rule)
        m2 = hba_astar(target, source, olb, clb, clf, catb, d, pt, tablename,
                       col_geom, col_edge, col_revc, col_cost, col_target,
                       col_source, vertex_tablename, col_cat, col_vertex_geom,
                       col_name, col_rule)

    m = m1
    if m <= 0:
        m = m2

    plpy.info("cl:", len(clf) + len(clb))

    if m == 0:
        plpy.info("No path found. Inferring path")

    #Now, get the result
    return hba_buildPath(ps, pt, m, source, target, olf, olb)
Ejemplo n.º 26
0
def hba_adj(cat, source, target, p, tablename='routing', col_geom='geom', col_edge='id', col_cost='cost', col_source='source', col_target='target', col_revc='reverse_cost', col_cat='category', col_name='name', col_rule='rule'):
  if adj_plan == -1:
    global adj_plan
    global adj_plan_rev
    adj_plan_rev = plpy.prepare('\n\
    select a.*, st_distance_sphere(st_startpoint(a.geom), b.geom) + a.length * ' + str(heuristic_constant) + ' * (a.category + 1) as heuristic from ((select  \n\
        ' + col_geom + ' as geom, \n\
        ' + col_edge + ' as id, \n\
        ' + col_cost + ' as cost,\n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' + col_geom + ')) as length,\n\
        ' + col_target + ' as source, \n\
        ' + col_source + ' as target, \n\
        ' + col_cat + ' as category, \n\
        ' + col_name + ' as name from ' + tablename + '\n\
        ) union all (select  \n\
        st_reverse(' + col_geom + ') as geom, \n\
        ' + col_edge + ' as id, \n\
        ' + col_revc + ' as cost, \n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' + col_geom + ')) as length,\n\
        ' + col_source + ' as source,\n\
        ' + col_target + ' as target, \n\
        ' + col_cat + ' as category, \n\
        ' + col_name + ' as name from ' + tablename + ' )\n\
        ) a, (select st_startpoint(' + col_geom + ')  as geom from ' + tablename + ' where ' + col_source + ' = $3 or ' + col_target + ' = $3 limit 1) b \n\
                where source = $1 and category >= 0\n\
                and cost <> \'Infinity\''
             #Turn restrictions:
        + 'and ' + col_edge + ' not in (SELECT ' + col_rule + ' from ' + tablename + ' r where r.' + col_edge + ' = $2 and ' + col_rule + ' is not null)'
       , ['Integer', 'Integer', 'Integer'])
    adj_plan = plpy.prepare('\n\
    select a.*, st_distance_sphere(st_startpoint(a.geom), b.geom) + a.length * ' + str(heuristic_constant) + ' * (a.category + 1) as heuristic from ((select  \n\
	st_reverse(' + col_geom + ') as geom, \n\
	' + col_edge + ' as id, \n\
	' + col_revc + ' as cost,\n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' + col_geom + ')) as length,\n\
	' + col_target + ' as source, \n\
	' + col_source + ' as target, \n\
	' + col_cat + ' as category, \n\
	' + col_name + ' as name from ' + tablename + '\n\
	) union all (select  \n\
	' + col_geom + ' as geom, \n\
	' + col_edge + ' as id, \n\
	' + col_cost + ' as cost, \n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' + col_geom + ')) as length,\n\
	' + col_source + ' as source,\n\
	' + col_target + ' as target, \n\
	' + col_cat + ' as category, \n\
	' + col_name + ' as name from ' + tablename + ' )\n\
	) a, (select st_startpoint(' + col_geom + ')  as geom from ' + tablename + ' where ' + col_source + ' = $3 or ' + col_target + ' = $3 limit 1) b \n\
		where source = $1 and category >= 0\n\
		and cost <> \'Infinity\''
             #Turn restrictions:
	+ 'and ' + col_edge + ' not in (SELECT ' + col_rule + ' from ' + tablename + ' r where r.' + col_edge + ' = $2 and ' + col_rule + ' is not null)'
       , ['Integer', 'Integer', 'Integer'])
  try:
    last_id = int(p[int(source)][1]['id'])
  except:
    last_id = -1
 
#  plpy.info([source, last_id, target])
  if "source" in col_source:
    return plpy.execute(adj_plan, [source, last_id, target])
  else:
    return plpy.execute(adj_plan_rev, [source, last_id, target])
Ejemplo n.º 27
0
def hba_star_pl(source, target, tablename='routing', col_edge='id', col_cost='cost', col_revc='reverse_cost', col_rule='rule', col_source='source', col_target='target', col_geom='the_geom', col_name='name', col_cat='category', vertex_tablename='vertex', col_vertex_geom='geom'):
  
  #Closed Lists (backward and forward)
  clf = []
  clb = []

  #Open Lists (backward and forward)
  #Candidate nodes from which we want to continue calculating
  #Every node (key) contains (value) its estimated (heuristic) cost till the target
  olf = {}
  olb = {}
  
  #Total cost (backward and forward)
  #For every node, globally, its lowest cost from source/target
  d = {}
  d[target] = 0
  d[source] = 0

  #Predecessor array (backward and forward)
  #For every node, which is its previous node (related to d[])
  ps = {}
  pt = {}

  #Current category of search (backward and forward)
  catf = [10]
  catb = [10]

  #Initial values
  olf[source] = d[source] + hba_heuristic(source, target, vertex_tablename, col_vertex_geom, col_edge)
  olb[target] = d[target] + hba_heuristic(target, source, vertex_tablename, col_vertex_geom, col_edge)

  global adj_plan
  global adj_plan_rev
  global central_node_plan
  
  adj_plan_rev = plpy.prepare('select a.*, '
	+ 'CASE WHEN a.name = $4 AND a.category <= 3 THEN \n\
		(a.length + st_distance_sphere(st_startpoint(a.geom), b.geom)) * (a.category + 1) \n\
	WHEN a.name = b.name THEN \n\
                a.length + st_distance_sphere(st_startpoint(a.geom), b.geom) \n\
	ELSE \n\
		(a.length + st_distance_sphere(st_startpoint(a.geom), b.geom)) * ' + str(heuristic_constant) + ' * (a.category + 1) \n\
	END as heuristic \n\
	from ((select  \n\
        ' + col_geom + ' as geom, \n\
        ' + col_edge + ' as id, \n\
        ' + col_cost + ' as cost,\n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' + col_geom + ')) as length,\n\
        ' + col_target + ' as source, \n\
        ' + col_source + ' as target, \n\
        ' + col_cat + ' as category, \n\
        ' + col_name + ' as name from ' + tablename + '\n\
        ) union all (select  \n\
        st_reverse(' + col_geom + ') as geom, \n\
        ' + col_edge + ' as id, \n\
        ' + col_revc + ' as cost, \n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' + col_geom + ')) as length,\n\
        ' + col_source + ' as source,\n\
        ' + col_target + ' as target, \n\
        ' + col_cat + ' as category, \n\
        ' + col_name + ' as name from ' + tablename + ' )\n\
        ) a, (select st_startpoint(' + col_geom + ')  as geom from ' + tablename + ' where ' + col_source + ' = $3 or ' + col_target + ' = $3 limit 1) b \n\
                where source = $1 and category >= 0\n\
                and cost <> \'Infinity\''
             #Turn restrictions:
        + 'and ' + col_edge + ' not in (SELECT ' + col_edge + ' from ' + tablename + ' r where r.' + col_rule + ' = $2)'
       , ['Integer', 'Integer', 'Integer', 'text', 'Integer'])

  adj_plan = plpy.prepare('\n\
    select a.*,'
        + 'CASE WHEN a.name = $4 AND a.category <= 3 THEN \n\
                (a.length + st_distance_sphere(st_startpoint(a.geom), b.geom))  * (a.category + 1) \n\
        WHEN a.name = b.name THEN \n\
                a.length + st_distance_sphere(st_startpoint(a.geom), b.geom) \n\
        ELSE \n\
                (a.length + st_distance_sphere(st_startpoint(a.geom), b.geom)) * ' + str(heuristic_constant) + ' * (a.category + 1) \n\
        END as heuristic \n\
        from ((select  \n\
	st_reverse(' + col_geom + ') as geom, \n\
	' + col_edge + ' as id, \n\
	' + col_revc + ' as cost,\n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' + col_geom + ')) as length,\n\
	' + col_target + ' as source, \n\
	' + col_source + ' as target, \n\
	' + col_cat + ' as category, \n\
	' + col_name + ' as name from ' + tablename + '\n\
	) union all (select  \n\
	' + col_geom + ' as geom, \n\
	' + col_edge + ' as id, \n\
	' + col_cost + ' as cost, \n\
        st_distance_sphere(st_startpoint(' + col_geom + '), st_endpoint(' + col_geom + ')) as length,\n\
	' + col_source + ' as source,\n\
	' + col_target + ' as target, \n\
	' + col_cat + ' as category, \n\
	' + col_name + ' as name from ' + tablename + ' )\n\
	) a, (select st_startpoint(' + col_geom + ')  as geom  from ' + tablename + ' where ' + col_source + ' = $3 or ' + col_target + ' = $3 limit 1) b \n\
		where source = $1 and category >= 0\n\
		and cost <> \'Infinity\''
             #Turn restrictions:
	+ 'and ' + col_edge + ' not in (SELECT ' + col_rule + ' from ' + tablename + ' r where r.' + col_edge + ' = $2 and ' + col_rule + ' is not null)'
       , ['Integer', 'Integer', 'Integer', 'text', 'Integer'])
 
  central_node_plan = plpy.prepare('SELECT 1 WHERE NOT EXISTS(SELECT 1 FROM ' + tablename + ' WHERE ' + col_edge + ' = $2 and ' + col_rule + ' = $1)', ['Integer', 'Integer'])

  #Star two-sided A* search

  m = -1
  m1 = 0
  m2 = 0

  #We try A* step by step until the two paths collided
  while not m1 and not m2 and (len(olf) > 0 and len(olb) > 0):
    m1 = hba_astar(source, target, olf, clf, clb, catf, d, ps, tablename, col_geom, col_edge, col_cost, col_revc, col_source, col_target, vertex_tablename, col_cat, col_vertex_geom, col_name, col_rule)
    m2 = hba_astar(target, source, olb, clb, clf, catb, d, pt, tablename, col_geom, col_edge, col_revc, col_cost, col_target, col_source, vertex_tablename, col_cat, col_vertex_geom, col_name, col_rule)

  m = m1
  if m <= 0 :
    m = m2

  plpy.info("cl:", len(clf) + len(clb))

  if m == 0:
    plpy.info("No path found. Inferring path")

  #Now, get the result
  return hba_buildPath(ps, pt, m, source, target, olf, olb)