gbfs icon indicating copy to clipboard operation
gbfs copied to clipboard

Geofencing refactor

Open mplsmitch opened this issue 2 years ago • 9 comments

MobilityData has been working on a refactor of the geofencing_zones.json file. The geofencing endpoint was added to the specification starting with v2.1 in early 2020. Since that time we've heard that it's has been a source of confusion for both data producers and consumers. Before opening a PR, we'd like to solicit feedback on a proposed solution. Because this has been a difficult topic for people to get their heads around, we've outlined our proposal in this explainer video. Please have a look and let us know what you think.

https://user-images.githubusercontent.com/15235861/151430511-eb360e3c-9bbf-4dfd-8955-362db917e3c7.mp4

If there's general agreement to go forward with this approach, we'll open a PR and try to roll it into v3.0. If that's not that case we'll go ahead with the v3.0 release as-is and push the refactor of geofencing to a later release.

Is your potential solution a breaking change?

  • [x] Yes
  • [ ] No
  • [ ] Unsure

mplsmitch avatar Jan 27 '22 19:01 mplsmitch

I would like to offer a few suggestions to for the Geofencing refactor effort. Below you'll find our ideas, please feel free to ask for more details if needed.

  1. Geofence Zones assumptions: currently the specification states that "By default, no restrictions apply everywhere. Geofencing zones SHOULD be modeled according to restrictions rather than allowance". This creates situations where data producers are forced to create zones where rules apply to the external area of their polygons, for instance when defining their zone of operation. We would like to suggest that if geofencing_zones.json is present on the GBFS feed, all areas not defined by the feed are considered disallowed. This would allow providers to define their operational area first and then restrictions that might apply and it is needed for the next suggestion.

  2. Remove polygons applying rules to external areas: we would also like to suggest that all zones defined have rules that apply to the internal area of their polygons. Allowing rules to apply to the exterior area of a polygon makes it harder for consumers to properly use the data, creates confusion to data producers and also creates edge cases that can break the geofence zone definition.

    • One such edge case can be seen on the example shown on the slide at the 5:35 min mark on the video. The service area defined here allows for users to ride vehicles outside the defined geofence (not park, just ride), which makes it possible for users to go outside the provider business area by any distance (I could potentially ride to a different city and come back) and also allows users to potentially break ride through rules in a neighbor city (since a user could potentially get a vehicle from Rotterdam and ride to Hague - which is close by - where the ride through rules might simply not be defined by the provider, since it's outside the Rotterdam service area).

    • Another potential issue is that rules defined to the outside area of a polygon apply to the rest of the world. That means that if you want to define an area of operation for the city of Rotterdam and another one for The Hague, they could cancel each other out (e.g. if no parking is allowed outside the Rotterdam zone and no parking is allowed outside of The Hague, in practice means that no parking is allowed anywhere).

  3. Overlapping zones: overlapping zones are fine, if it is clear on the spec in which order they should be treated.

  4. Classification of zones: the Mobility Data suggestion of creating an Enum for classification (4:53 min on the video) on the geofence zone spec looks good, but we believe this classification should actually take over from other boolean fields (like ride_allowed and ride_through_allowed), since it would make it easier for future expansion. Our suggestion is that the Enum should have elements like service area, parking area, ride through area, etc and maybe a boolean for allowed/disallowed. That way, we can easily add more classifications if needed in the future (like mandatory station parking area, for instance) with easy backwards compatibility (avoiding combinatorial explosion of lots of booleans and how they interact with each other).

  5. Field naming: if possible update field naming to better reflect what they do (ride_allowed is actually about parking, start and stop of rides, for instance).

mtborges avatar Feb 01 '22 18:02 mtborges

Tagging those who had interest in this topic at the Developer's Workshop: @cmonagle @viestat @richtaylor-ito @nbdh @freemvmt @balazsczap @ezmckinn @testower

josee-sabourin avatar Feb 10 '22 16:02 josee-sabourin

Adam from TIER: we are generally welcome the proposed changes, as it would maintain consistency with GeoJSON spec and clarify rules applications.

On the other hand, though, we support @mtborges alternative suggestions, especially on the first 2 points. We need to use feeds with multiple service areas in them, exterior rules would be problematic to manage (2) in those feeds due to overlapping issues (ofc rule priorities would help here but still hard to manage). This comes together with the "disallowed if not present" point (1), we do support that as well. (4) and (5) points are nice to have either.

Would be interested in other opinions as well on this topic!

tadam313 avatar Feb 18 '22 10:02 tadam313

if geofencing_zones.json is present on the GBFS feed, all areas not defined by the feed are considered disallowed.

Can you elaborate on what you mean by "disallowed"?

On item number 2, it's common practice to allow users to take vehicles outside the service area so I don't think you can call this an edge case, here's an example on Rotterdam https://nl.go-sharing.com/en/bikesharing/ The practice may vary by vehicle type but generally if you rent a bicycle, it can be ridden anywhere privately owned bicycles can be ridden, regardless of where the service area boundary is. If you rent a moped, where it can be ridden is determined by local law.

On item number 4, I'm not sure I understand the combination of Enum and Boolean and how that's simpler. For example, how would you handle the max speed rule which is an integer, not a boolean? Can you give an example? Also the mandatory station parking area rule has already passed in #349.

On item 5, I agree these need to change. I didn't include it in the video above. I think starting and ending of rentals should be separate rules, for example ride_start and ride_end or rental_allowed and parking_allowed. I've seen systems where rentals are allowed where parking is prohibited because it allows the operator to get users to return improperly parked vehicles to spaces where parking is permitted.

mplsmitch avatar Mar 01 '22 21:03 mplsmitch

@mplsmitch, thank you so much for making such a clear explanation of the problem and the proposed solution. I feel it really represents what was discussed in the workshop!

Form Dott's perspective here are our comments:

New fields

Classification

This is an interesting concept, I think that this would be useful to prevent confusion regarding which polygon is what, but I think we should take a step forward (or back would be more accurate :D) and consider that since limitation_area polygons can only be defined within service_area polygons the original "holes" approach works quite well in leveraging the GeoJSON spec to enforce that limitation since holes can only be created within a polygon (service_area in this case).

Orientation

I think more often than not, applying rules to the outside make things more complicated. Particularly in the case of two (relatively) near service_area polygons with conflicting exterior rules as already raised by @mtborges in his earlier comment (point number 2).

If we assume anything outside of a service_area polygon as fully limited area, then it is easier to limit specific areas within the service_area polygon using the appropriate limitation_area polygons. But I guess in our case we will just not define external orientation rules (other than maybe no riding and no parking).

Expressiveness

There is also the need to have more expressive configuration flags to accurately describe our business model, so I am happy to see that in the previous comments this has already been addressed/flagged.

In general it would be great to indeed split start and end ride.

viestat avatar Mar 21 '22 17:03 viestat

Regarding the disallowing of anything outside the service area polygon, here are a couple of examples of systems that explicitly allow vehicles to travel outside service areas.

This example comes from Go sharing which rents mopeds, ebikes and cars in the Netherlands:

Screen Shot 2022-03-30 at 10 17 05 AM

This example comes from ShareNow which operates car sharing all over Europe:

Screen Shot 2022-03-30 at 10 20 23 AM

In both of these examples, users are permitted to leave the service area but are prohibited from ending rentals outside of it.

On the original "holes" approach, nothing in the above proposal would prohibit holes in a polygon if the use case called for them. The intention was to do away with the coordinate orientation as a means of distinguishing between services areas and limitation areas.

The feedback we got was that applying rules to negative space (holes) was confusing and not consistently applied. For example, if for whatever reason the publisher didn't define a service area, only limitation areas, then the order of limitation area points would often be reversed to comply with the geoJSON spec which requires that the first ring in any polygon be counter-clockwise.

This could be addressed by requiring a service area polygon in all geofencing files but as there are many examples of systems that allow vehicles to leave the service area, it seems like there might also be cases where limitation areas would be defined outside of the service area polygon. If we define limitation areas as clockwise (holes) then any limitation areas outside the service area would be out of compliance with the GeoJSON RFC.

Since this issue with the application of rules to the outside of polygons is a result of aggregating data sets, couldn't there be a way to associate geofence rules with the systems for which they are published and not apply them to vehicles from other data sets?

Geofencing isn't the only business rule that differs across systems in different geographies - for example you might have differences in pricing, dates and hours of operation, system alerts etc and those aren't causing problems for aggregators, at least not that i'm aware of.

What if we changed system_id to a UUID and used it to identify both the GeoJSON and the fleet of vehicles that it applies to? Then if there's a rule applied to the outside of a service area, you would know not to apply it to vehicles from a neighboring system. And you could still enforce limitation areas like speed or other travel restrictions for vehicles that travel across systems.

mplsmitch avatar Mar 30 '22 16:03 mplsmitch

Answers inline to a few comments above:

From mplsmitch on Mar 1st, 2022 Can you elaborate on what you mean by "disallowed"?

Our suggestion is that for providers that add any geofencing_zones.json, everything that is not explicitly allowed on geofences (parking, riding, etc) is considered prohibited for any routing purposes on trip planning apps or data consumers. The current definition on GBFS would not change if a provider does not have any geofencing_zones.json, in other words, no geofences means no restrictions.

From mplsmitch on Mar 1st, 2022 On item number 2, it's common practice to allow users to take vehicles outside the service area so I don't think you can call this an edge case, here's an example on Rotterdam https://nl.go-sharing.com/en/bikesharing/ The practice may vary by vehicle type but generally if you rent a bicycle, it can be ridden anywhere privately owned bicycles can be ridden, regardless of where the service area boundary is. If you rent a moped, where it can be ridden is determined by local law.

This is a good point on providers allowing rides outside service areas, but we still stand by the argument that having geofences rules applying to internal and external areas is confusing and creates unnecessary complexity to both GBFS producers and data consumers. For a situation where you can ride outside the regular business or park area, providers can add a sufficiently large ride area defined as a geofence. Sometimes this type of roaming is explicitly limited on the provider's website. ShareNow actually calls this out on their FAQ:

image

From mplsmitch on Mar 1st, 2022 On item number 4, I'm not sure I understand the combination of Enum and Boolean and how that's simpler. For example, how would you handle the max speed rule which is an integer, not a boolean? Can you give an example? Also the mandatory station parking area rule has already passed in https://github.com/NABSA/gbfs/pull/349.

This particular example would use a list of multiple rules. It would apply only to boolean fields (not max speed, then), making it easier to expand that list in the future. One example (the name classification here is not final, simply what I thought in the moment):

"rules": [
    {
       "vehicle_type_id": [ ... ]
       "classification": RIDE_ALLOWED
       "maximum_speed_kpm": 20
   },
    {
       "vehicle_type_id": [ ... ]
       "classification": PARKING_NOT_ALLOWED
   },
]

From viestat on Mar 21st, 2022 I think more often than not, applying rules to the outside make things more complicated.

100% agreed. I believe having rules on the outside of the geofence makes interpretation of rules, feed production and feed consumption more complex overall. The two approaches (using GeoJSON holes and explicit orientations) are different in format, but they retain the main source of confusion and complexity with outside rules.

From mplsmitch on Mar 30th, 2022 Since this issue with the application of rules to the outside of polygons is a result of aggregating data sets, couldn't there be a way to associate geofence rules with the systems for which they are published and not apply them to vehicles from other data sets? Geofencing isn't the only business rule that differs across systems in different geographies - for example you might have differences in pricing, dates and hours of operation, system alerts etc and those aren't causing problems for aggregators, at least not that i'm aware of. What if we changed system_id to a UUID and used it to identify both the GeoJSON and the fleet of vehicles that it applies to? Then if there's a rule applied to the outside of a service area, you would know not to apply it to vehicles from a neighboring system. And you could still enforce limitation areas like speed or other travel restrictions for vehicles that travel across systems.

This would probably help a lot, but I believe it would be a broader discussion about how to represent multiple systems in a single GBFS feed set.

mtborges avatar Mar 30 '22 19:03 mtborges

For a situation where you can ride outside the regular business or park area, providers can add a sufficiently large ride area defined as a geofence.

TheShareNow example above is an extreme case but according the the chart, if the car were rented in Italy a geofence covering a "sufficiently large ride area" would have to include Switzerland, Austria, Germany, France, Luxembourg and Lichtenstein. Given that:

everything that is not explicitly allowed on geofences (parking, riding, etc) is considered prohibited.

users would be prohibited from driving in any of those countries unless they were included in the geofencing_zones file.

I'm all in favor of making things less complicated but needing to explicitly allow everything seems much more complicated than applying limitations. Even in the example above it says:

"classification": PARKING_NOT_ALLOWED

What happens when an operator allows scooter rides throughout a service area that has a highway running through it where they are prohibited by law? If rules are based in limitations in stead of allowances, you can make the argument that there may be places where it's not appropriate to ride that aren't covered by the geofencing file. If you're explicitly saying that something is "allowed" where it shouldn't be like a highway or private property, that's a much harder case to make.

mplsmitch avatar Mar 30 '22 21:03 mplsmitch

This was discussed at the Mobility Data Developer's Workshop today, here are some notes from where we landed:

  • Polygons should define the interior (never the exterior)
  • if geofencing is not present, there are no restrictions. But if geofencing is present, restrictions apply by default.
  • If ride-through is allowed outside the main service zone, the provider should provide a polygon corresponding with the maximum possible reach of the vehicle (ie North America)
  • In the case of overlapping geo-fences, the applicable rules are only provided from the prioritized zone.
  • Polygons should not be additive, but rather should represent the entirety of the rules applicable in that area (so in the case of overlap, the most prioritized shape will be the only applicable shape).

cmonagle avatar Jun 06 '22 19:06 cmonagle

Closing this issue since it has now been resolved by #481

josee-sabourin avatar Mar 13 '23 14:03 josee-sabourin