Exemple #1
0
 def fix_onepoint(block):
    points = gml.flat_to_xys(block.geometry_wkt)
    if len(points) == 3:
       # remove extra point, we don't need it anymore
       del points[1]
       block.geometry_wkt = (
          'LINESTRING(%s)' % (gml.wkt_coords_format(points),))
Exemple #2
0
 def __init__(self, obs, cutoff_distance):
    if len(obs) > 1:
       self.geometry_wkt = (
          'LINESTRING(%s)' % (gml.wkt_coords_format(obs),))
    else:
       self.geometry_wkt = 'POINT(%s %s)' % (obs[0][0], obs[0][1],)
    self.cutoff = cutoff_distance
Exemple #3
0
   def split_block(self, b, intersection, new_node_id=None):
      points = gml.flat_to_xys(b.geometry_wkt)
      index = get_point_index(b, intersection)

      # Insert the new vertex into the byway
      points.insert(index, intersection)

      # Split the byway at the new vertex
      new_split_block = copy.deepcopy(b)
      new_split_block.stack_id = self.get_fresh_id()
      new_split_block.split_from_stack_id = b.stack_id
      geom1 = list()
      geom2 = list()
      # TODO: this can be done without a for loop
      for i in range(0,len(points)):
         if (i <= index):
            geom1.append(points[i])
         if (i >= index):
            geom2.append(points[i])

      if (new_node_id is None):
         new_split_block.nid2 = self.get_fresh_id()
      else:
         new_split_block.nid2 = new_node_id
      b.nid1 = new_split_block.nid2
   
      # Remove the old split block since its geometry has changed
      for block in self.new_byways:
         if block.stack_id == b.stack_id:
            self.new_byways.remove(block)
            break

      # Save the new split blocks to the byways list
      new_split_block.geometry_wkt = (
         'LINESTRING(%s)' % (gml.wkt_coords_format(geom1),))
      self.new_byways.append(new_split_block)
      b.geometry_wkt = (
         'LINESTRING(%s)' % (gml.wkt_coords_format(geom2),))
      self.new_byways.append(b)
      return b.nid1, new_split_block.stack_id, b.stack_id
Exemple #4
0
   def create_new_block(self, obs, bounds, last_block_ids=None):
      first_point_index = bounds[0]
      last_point_index = bounds[1]

      new_block = BywayMeta(self.get_fresh_id(),
                            'New Block',
                            self.get_fresh_id(),
                            self.get_fresh_id(),
                            0,
                            0,
                            0,
                            None,
                            None,
                            1)

      new_block_points = []
      one_point = False
      for i in range(first_point_index, last_point_index+1):
         new_block_points.append((obs[i][0], obs[i][1]))
      if (len(new_block_points) == 1):
         # Single points need to be handled differently, because when connecting
         # to nearby blocks the point may be moved
         one_point = True
         new_block_points.append(new_block_points[0])
      new_block.geometry_wkt = (
         'LINESTRING(%s)' % (gml.wkt_coords_format(new_block_points),))

      # Extend byway both ways and split (or connect if end node near enough)
      ignore_ids = self.continue_block(new_block, -1, last_block_ids)
      if (one_point):
         fix_onepoint(new_block)
      ignore = [new_block.stack_id]
      if (one_point and ignore_ids is not None):
         ignore.extend(ignore_ids)
      self.continue_block(new_block, 1, ignore=ignore)
      
      if (one_point):
         fix_onepoint(new_block)

      # Smooth new byway geometry
      new_block.geometry_wkt, new_block.geometry_svg = (
         self.smooth_path(new_block.geometry_wkt))

      # Save byway to block cache
      #new_block.geometry_wkt = 'LINESTRING(%s)' % (
      #   gml.wkt_coords_format(new_block.geometry_wkt),)
      self.new_byways.append(new_block)

      return new_block
Exemple #5
0
    def from_gml(self, qb, elem):

        geofeature.One.from_gml(self, qb, elem)
        # BUG nnnn: Make tracks revisionless. Uncomment this:
        # self.setup_item_revisionless_defaults(qb, force=True)

        xys_string = list()
        for tpoint in elem:
            tp = track_point.One()
            tp.from_gml(qb, tpoint)
            self.track_points.append(tp)
            xys_string.append((float(tp.x), float(tp.y)))
        self.set_geometry_wkt(
            gml.wkt_linestring_get(gml.wkt_coords_format(xys_string)))

        if not self.track_points:
            log.warning('from_gml: no track_points: %d' %
                        (len(self.track_points), ))
Exemple #6
0
   def from_gml(self, qb, elem):

      geofeature.One.from_gml(self, qb, elem)
      # BUG nnnn: Make tracks revisionless. Uncomment this:
      # self.setup_item_revisionless_defaults(qb, force=True)

      xys_string = list()
      for tpoint in elem:
         tp = track_point.One()
         tp.from_gml(qb, tpoint)
         self.track_points.append(tp)
         xys_string.append((float(tp.x), float(tp.y)))
      self.set_geometry_wkt(gml.wkt_linestring_get(
                              gml.wkt_coords_format(xys_string)))

      if not self.track_points:
         log.warning('from_gml: no track_points: %d'
                     % (len(self.track_points),))
Exemple #7
0
   def continue_block(self, new_block, direction, last_block_ids=None,
                      ignore=None):
      if direction == -1:
         endpoint_index = 0
      else:
         endpoint_index = -1

      extending_points = gml.flat_to_xys(new_block.geometry_wkt)
      
      if ignore is None:
         ignore = [new_block.stack_id]
      # If there are no blocks nearby, no need to extend this block
      nearest_block = self.get_nearest_block(
         extending_points[endpoint_index],
         last_block_ids,
         ignore=ignore)
      if (nearest_block is None
          or nearest_block.dist > self.wtem.distance_error):
         return None
      ignore_ids = [nearest_block.stack_id]

      near_points = gml.flat_to_xys(nearest_block.geometry_wkt)

      # If we are close to an endpoint of another block, connect to it.
      if (dist(extending_points[endpoint_index], near_points[0])
          <= self.wtem.distance_error):
         # add blocks that connect to that endpoint to ignore list for next
         # block continuation
         ignore_ids.extend(
            [b.stack_id for b in self.get_connected_blocks(
               nearest_block, nearest_block.nid1)])
         if direction == -1:
            extending_points[0] = near_points[0]
            new_block.nid1 = nearest_block.nid1
         else:
            extending_points[-1] = near_points[0]
            new_block.nid2 = nearest_block.nid1
      elif (dist(extending_points[endpoint_index], near_points[-1])
            <= self.wtem.distance_error):
         # add blocks that connect to that endpoint to ignore list for next
         # block continuation
         ignore_ids.extend(
            [b.stack_id for b in self.get_connected_blocks(
               nearest_block, nearest_block.nid2)])
         if direction == -1:
            extending_points[0] = near_points[-1]
            new_block.nid1 = nearest_block.nid2
         else:
            extending_points[-1] = near_points[-1]
            new_block.nid2 = nearest_block.nid2
      else:
         # Get location of closest point on the nearest block and the expected
         # index in that block's sequence of points.
         point = self.proj_block(
            extending_points[endpoint_index], nearest_block)

         new_node, b1_id, b2_id = self.split_block(nearest_block, point)
         ignore_ids = [b1_id, b2_id]

         # Connect the current block to the intersection
         if direction == -1:
            extending_points.insert(0, point)
            new_block.nid1 = new_node
         else:
            extending_points.append(point)
            new_block.nid2 = new_node
      
      new_block.geometry_wkt = (
         'LINESTRING(%s)' % (gml.wkt_coords_format(extending_points),))
      return ignore_ids
Exemple #8
0
    def save_rstep(self, qb, route, step_number):

        self.route_id = route.system_id
        # FIXME: Do we need these? They're in the table...
        self.route_stack_id = route.stack_id
        self.route_version = route.version

        self.step_number = step_number

        g.assurt(self.byway_stack_id > 0)
        g.assurt(self.byway_version > 0)
        # 2014.08.19: flashclient sending byway_id="0" ???
        if (not self.byway_id) or (self.byway_id <= 0):
            if route.stack_id not in One.warned_re_sysid_stk_ids:
                One.warned_re_sysid_stk_ids.add(route.stack_id)
                log.warning(
                    'save_rstep: byway_id not sent from client: route sid: %s'
                    % (route.stack_id, ))
            branch_ids = [str(branch_tup[0]) for branch_tup in qb.branch_hier]
            # FIXME: The ORDER BY is pretty lame... but if we just have a stack ID
            #        and a version, and if we don't check against the time when
            #        the route was requested, we can't know for sure which branch
            #        the byway is from (e.g., a route was requested in a leafy
            #        branch and the parent branch's byways were selected, but
            #        then one byway is edited in both the parent and the leaf,
            #        then there are two byways with the same stack ID and version
            #        but different branch_ids: since our qb is Current but the
            #        route is historic, we would really need to find the revision
            #        when the route was requested and use that to find the true
            #        byway system_id). This code just finds the leafiest matching
            #        byway... which is probably okay, since this code is for
            #        saving byways, and most users will be saving to the basemap
            #        branch (who uses the MetC Bikeways 2012 branch, anyway? No
            #        one...), and also this code is just a stopgap until we fix
            #        the real problem that is the client is not sending byway
            #        system IDs, which might be a pyserver problem not sending
            #        them to the client in the first place....
            sys_id_sql = ("""
            SELECT iv.system_id
              FROM item_versioned AS iv
             WHERE iv.stack_id = %d
               AND iv.version = %d
               AND branch_id IN (%s)
             ORDER BY branch_id DESC
             LIMIT 1
            """ % (
                self.byway_stack_id,
                self.byway_version,
                ','.join(branch_ids),
            ))
            rows = qb.db.sql(sys_id_sql)
            g.assurt(
                len(rows) == 1)  # Or not, if no match, which would be weird.
            self.byway_id = rows[0]['system_id']
            g.assurt(self.byway_id > 0)

        if (self.geometry and (self.travel_mode == Travel_Mode.transit)):
            # Old CcpV1: db_glue automatically prepends the SRID for columns named
            # 'geometry' but we have to do it manually here so constraints pass.
            # 2012.09.27: What does 'constraints pass' mean? Doesn't db_glue fix
            #             this list the comment says?
            # MAYBE: This feels like a gml fcn. See maybe: wkt_linestring_get.
            wkt_geom = (
                'SRID=%s;LINESTRING(%s)' % (
                    conf.default_srid,
                    gml.wkt_coords_format(
                        # FIXED?: Was: gml.flat_to_xys(self.geometry[2:])
                        gml.flat_to_xys(self.geometry)),
                ))
        else:
            # Either this is a byway-associated route_step, so we don't save the
            # byway's geometry (it's easy to lookup in the database), or something
            # else...
            wkt_geom = None
            if self.travel_mode == Travel_Mode.transit:
                # FIXME: Does this mean we're clearing existing geometry? Seems
                #        weird...
                log.warning(
                    'save_rstep: transit step has geometry? are we clearing it?'
                )

        # FIXME: What about wkt_geom? Is this right?
        self.transit_geometry = wkt_geom

        self.save_insert(qb, One.item_type_table, One.psql_defns)