def update_shape_ajax(request, **kwargs): if request.method == 'POST': request_params = request.POST.dict() shape_id = request_params['id'] points = json.loads(request_params['points']) try: with transaction.atomic(): shape = Shape.objects.get(pk=shape_id) shape_points = shape.points.all() for shape_point in shape_points: shape_point.delete() for idx, point in enumerate(points): shape_point = ShapePoint(point='POINT ({} {})'.format( point['lng'], point['lat']), shape_id=shape.id, sequence=idx + 1) shape_point.save() shape.update_geometry() return http.HttpResponse(content='Shape updated successfully', status=200) except Exception as e: return http.HttpResponse( content='An error occurred while processing your request', status=400)
def test_import_shape_maximal(self): shape_txt = StringIO("""\ shape_id,shape_pt_lat,shape_pt_lon,shape_pt_sequence,shape_dist_traveled S1,36.425288,-117.133162,1,0 """) ShapePoint.import_txt(shape_txt, self.feed) shape = Shape.objects.get() self.assertEqual(shape.feed, self.feed) self.assertEqual(shape.shape_id, 'S1') self.assertEqual(shape.geometry, None) shape_pt = ShapePoint.objects.get() self.assertEqual(shape_pt.shape, shape) self.assertEqual(shape_pt.point.coords, (-117.133162, 36.425288)) self.assertEqual(shape_pt.sequence, 1) self.assertEqual(shape_pt.traveled, 0)
def test_import_shape_traveled_omitted(self): shape_txt = StringIO.StringIO("""\ shape_id,shape_pt_lat,shape_pt_lon,shape_pt_sequence,shape_dist_traveled S1,36.425288,-117.133162,1, """) ShapePoint.import_txt(shape_txt, self.feed) shape = Shape.objects.get() self.assertEqual(shape.feed, self.feed) self.assertEqual(shape.shape_id, 'S1') shape_pt = ShapePoint.objects.get() self.assertEqual(shape_pt.shape, shape) self.assertEqual(str(shape_pt.lat), '36.425288') self.assertEqual(str(shape_pt.lon), '-117.133162') self.assertEqual(shape_pt.sequence, 1) self.assertEqual(shape_pt.traveled, None)
def test_legacy_lat_long(self): shape = Shape.objects.create(feed=self.feed, shape_id='s1') shape_pt1 = ShapePoint(shape=shape, sequence=1) shape_pt1.lat = 36.425288 shape_pt1.lon = -117.133162 shape_pt1.save() shape_pt2 = ShapePoint(shape=shape, sequence=2) shape_pt2.lon = -117.14 shape_pt2.lat = 36.43 shape_pt2.save() self.assertEqual(shape_pt1.point.coords, (-117.133162, 36.425288)) self.assertEqual(shape_pt1.lat, 36.425288) self.assertEqual(shape_pt1.lon, -117.133162) self.assertEqual(shape_pt2.point.coords, (-117.14, 36.43)) self.assertEqual(shape_pt2.lat, 36.43) self.assertEqual(shape_pt2.lon, -117.14)
def test_import_shape_maximal(self): shape_txt = StringIO.StringIO( """\ shape_id,shape_pt_lat,shape_pt_lon,shape_pt_sequence,shape_dist_traveled S1,36.425288,-117.133162,1,0 """ ) ShapePoint.import_txt(shape_txt, self.feed) shape = Shape.objects.get() self.assertEqual(shape.feed, self.feed) self.assertEqual(shape.shape_id, "S1") shape_pt = ShapePoint.objects.get() self.assertEqual(shape_pt.shape, shape) self.assertEqual(str(shape_pt.lat), "36.425288") self.assertEqual(str(shape_pt.lon), "-117.133162") self.assertEqual(shape_pt.sequence, 1) self.assertEqual(shape_pt.traveled, 0)
def test_export_shape_minimal(self): shape = Shape.objects.create(feed=self.feed, shape_id='S1') ShapePoint.objects.create( shape=shape, point="POINT(-117.133162 36.425288)", sequence=1) shape_txt = ShapePoint.export_txt(self.feed) self.assertEqual(shape_txt, """\ shape_id,shape_pt_lat,shape_pt_lon,shape_pt_sequence S1,36.425288,-117.133162,1 """)
def test_import_shape_duplicate(self): shape_txt = StringIO("""\ shape_id,shape_pt_lat,shape_pt_lon,shape_pt_sequence S1,36.425288,-117.133162,1 S1,36.42,-117.13,1 S1,36.43,-117.14,2 """) ShapePoint.import_txt(shape_txt, self.feed) shape = Shape.objects.get() # Just one self.assertEqual(shape.feed, self.feed) self.assertEqual(shape.shape_id, 'S1') self.assertEqual(2, ShapePoint.objects.count()) shape_pt, shape_pt2 = ShapePoint.objects.order_by('sequence') self.assertEqual(shape_pt.shape, shape) self.assertEqual(shape_pt.point.coords, (-117.133162, 36.425288)) self.assertEqual(shape_pt.sequence, 1) self.assertEqual(shape_pt2.shape, shape) self.assertEqual(shape_pt2.point.coords, (-117.14, 36.43)) self.assertEqual(shape_pt2.sequence, 2)
def test_export_shape_empty(self): shape_txt = ShapePoint.export_txt(self.feed) self.assertFalse(shape_txt)
def new_trip(request, **kwargs): route = Route.objects.get(id=kwargs.get('route_id')) # Create route + shape context = dict() context.update(kwargs) context['headsign_options'] = route.desc.split('-') context['service_times'] = Service.objects.all() if request.method == 'POST': request_params = request.POST.dict() shape_file = shapefile.Reader(shp=request.FILES['shape-file'], dbf=request.FILES['shape-file-dbf']) stops_reader = DictReaderStrip(request.FILES['stops-file']) # Check required fields are present in the stops csv expected_fields = set([ 'stop_sequence', 'lat', 'lon', 'stop_name', 'designation', 'location_type' ]) current_fields = set(stops_reader.fieldnames) if not expected_fields.issubset(current_fields): missing_fields = expected_fields.difference(current_fields) context[ 'error_message'] = 'The following columns are missing from the uploaded stops file: {}.'.format( missing_fields) return render(request, 'myapp/new-trip.html', context) # Trip variables headsign = request_params['headsign'] service_id = request_params['service-id'] direction = request_params['inbound'] route_id = kwargs['route_id'] # corridor + 4 characters for the route number corridor = route.route_id[0] route_number = route.route_id[5:9] origin = request_params['origin'] route_variation = request_params['route-variation'] shape_id = "{}{}{}{}{}".format(corridor, route_number, origin, route_variation, direction) trip_id = shape_id with transaction.atomic(): # Create new shape shape = Shape(feed_id=kwargs['feed_id'], shape_id=shape_id) shape.save() trip = Trip(trip_id=trip_id, headsign=headsign, service_id=service_id, direction=direction, route_id=route_id, shape_id=shape.id) trip.save() # Create shape points from the uploaded shape files shapes = shape_file.shapes() sequence_start = 1001 # The trip line string is stored in layer 1 for idx, point in enumerate(shapes[1].points): shape_point = ShapePoint(point='POINT ({} {})'.format( point[0], point[1]), shape_id=shape.id, sequence=sequence_start + idx) shape_point.save() shape.update_geometry() start_seconds = 6 * 3600 # First trip is at 6am delta = 5 * 60 # % minutes for row in stops_reader: tmp = list(row['stop_name'].upper().replace(' ', '')) random.shuffle(tmp) stop_suffix = "".join( tmp[:3]) # pick 3 characters from the shuffled stop name stop, created = Stop.objects.get_or_create( point=geos.fromstr('POINT({} {})'.format( row['lon'], row['lat'])), feed_id=kwargs['feed_id'], defaults={ 'stop_id': '{}{}{}{}'.format(corridor.zfill(2), row['designation'] or 0, direction, stop_suffix), 'name': row['stop_name'], 'location_type': row['location_type'], }) trip.stoptime_set.add( StopTime(stop_id=stop.id, trip_id=trip.id, stop_sequence=int(row['stop_sequence']) + 1, arrival_time=start_seconds, departure_time=start_seconds)) start_seconds += delta trip.save() trip.update_geometry() trip.refresh_from_db() return http.HttpResponseRedirect( reverse('route_detail', kwargs={ 'pk': kwargs['route_id'], 'feed_id': kwargs['feed_id'], 'agency_id': kwargs['agency_id'] })) return render(request, 'myapp/new-trip.html', context)