One of this package’s seven data sources — one of the four online
services. vignette("data-sources") is the overview and puts
it in context.
The Province of British Columbia runs the BC Address Geocoder, a public, keyless service over the province’s own site and parcel registries. It is the highest quality address source this package can reach, and it covers one province.
bc_geocode() is the binding, "bc" is a
geocode() tier, and bc_validate() re-asks it
about an answer you already have.
What this adds to the package
A second opinion from an authority, which nothing else here
provides. geocode() cannot tell you whether its
own answer is right — every offline tier reads NAR, so a NAR error is
invisible from the inside. BC’s geocoder is a provincial address
authority built on parcels and a site registry, not a compilation of
what others supplied, and where it and NAR disagree BC’s answer
is the more reliable of the two. That is what
bc_validate() is for.
It also adds coverage, though less than the quality would suggest. As a tier it places BC addresses the offline tiers miss; but the two sources plausibly share upstream data, so it is not independent of NAR and much of what NAR is missing in BC it is missing too.
And it is the source of the only calibration the package has of what
uncertainty_m = 0 is actually worth.
uncertainty_m measures error this package adds
relative to NAR’s point, and says nothing about NAR’s own error; BC is
the one place that second quantity has been measured at all — see
vignette("source-nar").
Licence
Every response carries its own copyright notice and licence link:
Copyright © 2024 Province of British Columbia
under the Open Government Licence – British
Columbia. That composes with the Statistics Canada Open Licence
covering NAR, so BC coordinates can be mixed into a result without
further conditions — unlike the ODbL data behind
osm_geocode(), which is why that one is not a tier.
Using it
bc_geocode("525 Superior St, Victoria, BC") |>
select(match_method, uncertainty_m, bc_score, bc_precision, bc_descriptor,
bc_accuracy, lon, lat)
#> match_method uncertainty_m bc_score bc_precision bc_descriptor bc_accuracy lon lat
#> 1 bc_civic 20 100 CIVIC_NUMBER parcelPoint high -123.3709 48.4177As a tier, and as a validator:
g <- geocode(c("525 Superior St, Victoria, BC", "800 Robson St, Vancouver, BC"),
method = c("nar", "bc"))
bc_validate(g) |>
select(input, match_method, bc_match_method, bc_precision, bc_dist_m)
#> input match_method bc_match_method bc_precision bc_dist_m
#> 1 525 Superior St, Victoria, BC nar_building bc_civic CIVIC_NUMBER 6.864790e+00
#> 2 800 Robson St, Vancouver, BC bc_civic bc_civic CIVIC_NUMBER 1.253831e-09bc_dist_m is how far BC’s answer sits from the one
already obtained, and it is the column to sort on when looking for
suspect rows. Note the second row: it was placed by the
"bc" tier in the first place, so validating it re-asks the
source that already answered and the distance is zero by construction.
Validation only says something about rows an offline tier
placed.
What to watch out for
The service always answers
Feed it something that does not exist and it does not fail — it returns the centre of the locality:
bc_geocode("1234 Nonexistentzzz Rd, Victoria, BC") |>
select(match_method, bc_score, bc_precision, bc_address, bc_faults)
#> match_method bc_score bc_precision bc_address bc_faults
#> 1 none 48 LOCALITY Victoria, BC LOCALITY_INITIAL_GARBAGE notAllowedSo the presence of a result says nothing. matchPrecision
is the field that decides what was actually resolved, and
match_method is derived from it: bc_site and
bc_civic are addresses, bc_block is
interpolated along a block, and bc_street and
bc_locality are answers about a place rather than
an address. min_score additionally rejects matches the
service itself scored poorly, and bc_faults says why it
did.
Which point on the property you get — and which one you asked for
BC holds several different points for one address, and
locationDescriptor selects among them. Their definitions
are the service’s own:
| descriptor | what it is |
|---|---|
parcelPoint |
a position known to be inside the parcel, usually the centroid |
rooftopPoint |
the roof of the house or building |
frontDoorPoint |
the front door or main entrance |
accessPoint |
on the curb or road edge, in the middle of the driveway or access lane |
routingPoint |
on the road centreline, directly in front of the access point |
any |
(the default) whatever main location it holds, falling back to the access point when it holds none |
one <- "525 Superior St, Victoria, BC"
lapply(c("any", "rooftopPoint", "accessPoint", "routingPoint"), function(d) {
bc_geocode(one, locationDescriptor = d) |>
transmute(asked = d, bc_descriptor, bc_accuracy, lon, lat)
}) |> bind_rows()
#> asked bc_descriptor bc_accuracy lon lat
#> 1 any parcelPoint high -123.3709 48.41770
#> 2 rooftopPoint parcelPoint high -123.3709 48.41770
#> 3 accessPoint accessPoint medium -123.3710 48.41808
#> 4 routingPoint routingPoint medium -123.3710 48.41811Asking does not mean getting, which is why
bc_descriptor reports what actually came back. The service
does not go looking for the kind of point you named; it returns the main
location it happens to hold. Over 400 NAR BC building points
(data-raw/probe_bc.R), frontDoorPoint,
rooftopPoint and parcelPoint each returned a
point identical to any on 100% of
addresses — the main location was a parcel point for 359 of the
400 and a rooftop for 19, and no request changed that. Only
accessPoint and routingPoint are genuinely
different points.
The default is the one closest to NAR
The NAR User Guide says a building representative point “may not
correspond exactly to the physical center of the building structure
itself” and may be the road access point or the driveway — which
describes BC’s accessPoint almost word for word, and
suggests the package should be asking for that one. Measured, it should
not. Distance from NAR’s own building point, on the 378 of 400 addresses
BC resolved cleanly under every descriptor:
| requested | p25 | p50 | p75 | p90 | within 10 m | within 25 m |
|---|---|---|---|---|---|---|
any / parcelPoint /
frontDoorPoint / rooftopPoint
|
1.6 m | 20.2 m | 50.7 m | 99.1 m | 38% | 57% |
accessPoint |
16.6 m | 28.9 m | 52.9 m | 98.7 m | 11% | 43% |
routingPoint |
19.1 m | 31.6 m | 54.7 m | 99.7 m | 6% | 36% |
Paired per address, accessPoint is a median 5.3 m
further from NAR than the default and routingPoint
7.7 m further. So the package’s default is already the right one, and
accessPoint is what to ask for when the road-side position
is what you actually want — routing, service delivery — rather than the
building.
The per-address picture is more interesting than the aggregate,
though. The default is the closest of the three on only
58% of addresses; accessPoint wins on 29%
and routingPoint on 13%. NAR’s building points are not
consistently one kind of point or the other — they are a mixture, which
is exactly what the User Guide’s hedge describes. There is no single BC
point that NAR is trying to be.
Note also the p25 column: the default agrees with NAR to within 1.6 m on a quarter of addresses. That is not two sources independently arriving at the same place — it is the same underlying record surfacing twice.
uncertainty_m for the bc_* tiers is not
measured
It is the one set of numbers in this package that was not derived
from data. BC publishes locationPositionalAccuracy as the
categorical high / medium / low /
coarse and no distance at all, so the metres attached to
bc_site, bc_civic and the rest are the
service’s precision semantics translated into deliberately pessimistic
order-of-magnitude figures. Treat them as a ranking that is safe to
filter on, not as an error bar comparable to the NAR tiers’.
bc_accuracy carries the categorical straight through,
and it is the more honest field of the two.
It covers British Columbia only
bc_validate() skips rows outside BC rather than sending
them, because the service would answer about a BC place of the same
name.
Where the measurements live
file.show(system.file("notes", "geocoding-status.md", package = "cangeocode"))data-raw/probe_bc.R reproduces the reference-point
comparison above; the geocoding status note carries the NAR-versus-BC
distance distributions and what they do and do not prove.
