/lib/Zaaksysteem/Geo/BAG.pm
Perl | 371 lines | 270 code | 93 blank | 8 comment | 15 complexity | f674cf131b8b9ff03b7eee45bff0e90a MD5 | raw file
- package Zaaksysteem::Geo::BAG;
- use Moose;
- use Zaaksysteem::Geo;
- use Data::Dumper;
- use constant SOURCE_TABLES => {
- nummeraanduiding => 'BagNummeraanduiding',
- openbareruimte => 'BagOpenbareruimte',
- woonplaats => 'BagWoonplaats'
- # Rest still unsupported
- };
- use constant ESSENTIAL_DATA => {
- BagNummeraanduiding => {
- parent => {
- table => 'BagOpenbareruimte',
- key => 'openbareruimte'
- },
- fields => {
- postcode => 'postcode',
- huisnummer => 'huisnummer',
- huisnummertoevoeging => 'huisnummertoevoeging',
- huisletter => 'huisletter',
- }
- },
- BagOpenbareruimte => {
- parent => {
- table => 'BagWoonplaats',
- key => 'woonplaats'
- },
- fields => {
- naam => 'straat',
- }
- },
- BagWoonplaats => {
- fields => {
- naam => 'woonplaats',
- }
- }
- };
- has 'apikey' => (
- 'is' => 'rw',
- 'lazy' => 1,
- 'default' => sub {
- my $self = shift;
- my $schema = $self->result_source->schema;
- #warn(Dumper($schema->default_resultset_attributes));
- return $schema
- ->default_resultset_attributes
- ->{config}
- ->{google_api_key}
- }
- );
- =head2 $component->geocode_term
- Return value: $geocode_address
- Generate a term for geocoding this location with a googlemaps or other
- geocoder.
- e.g:
- Nederland, Amsterdam, Donker Curtiusstraat 7
- Nederland, Amsterdam, Donker Curtiusstraat
- =cut
- sub geocode_term {}
- sub set_wsg_coordinates {
- my $self = shift;
- ### Only on component
- return unless UNIVERSAL::isa($self, 'DBIx::Class');
- return unless $self->can('coordinates_wsg');
- my $location = $self->get_wsg_location;
- if ($location) {
- $self->coordinates_wsg(
- join(',', @{ $location->{coordinates} })
- );
- $self->update;
- }
- }
- sub get_wsg_location {
- my $self = shift;
- my $term = shift;
- my $geocoder = Zaaksysteem::Geo->new(
- key => $self->apikey
- );
- my $location;
- eval {
- $geocoder->query($term || $self->geocode_term);
- $geocoder->geocode;
- if ($geocoder->success) {
- my $locationes = $geocoder->results;
- $location = shift( @{ $locationes });
- }
- };
- return $location;
- }
- =head2 $resultset->lookup_nearest_bag_object(geo_address)
- Return value: $BAG_ROW
- Given an arrayref of coordinates:
- $resultset->lookup_nearest_bag_object(
- 'Amsterdam, Donker Curtiusstraat 7'
- );
- Returns the nearest bag location
- =cut
- sub lookup_nearest_bag_object {
- my $self = shift;
- my $address = shift;
- return unless UNIVERSAL::isa($self, 'DBIx::Class::ResultSet');
- my $schema = $self->result_source->schema;
- my $location = $self->get_wsg_location($address);
- return unless $location;
- ### Find city
- my $city = $schema->resultset('BagWoonplaats')->search(
- {
- 'LOWER(naam)' => lc($location->city),
- }
- )->first or return;
- $address = lc($location->address);
- my ($streetname, $streetnumber) = $address =~ /^(.*?)\s+(\d.*)$/;
- unless ($streetname) {
- $streetname = $address;
- }
- my ($numberletter) = $streetnumber
- =~ /^\d+([a-z]+)/;
- my ($numbersuffix) = $streetnumber
- =~ /^\d+[a-z]+[\s-]+(.*)/i;
- $streetnumber =~ s/^(\d+).*/$1/;
- return unless $streetname;
- ### Find street
- my $street = $city->openbareruimten->search(
- {
- 'LOWER(naam)' => lc($streetname),
- }
- )->first or return;
- unless ($streetnumber) {
- return $street;
- }
- $address = $street->hoofdadressen->search(
- {
- 'huisnummer' => lc($streetnumber),
- }
- )->first or return $street;
- my $narrowaddress;
- unless (
- $numberletter &&
- (
- $narrowaddress = $address->search(
- {
- 'LOWER(huisletter)' => lc($numberletter)
- }
- )
- ) &&
- $narrowaddress->count
- ) {
- return $address;
- }
- my $suffixaddress;
- unless (
- $numbersuffix &&
- (
- $suffixaddress = $address->search(
- {
- 'LOWER(huisnummertoevoeging)' => lc($numbersuffix)
- }
- )
- ) &&
- $suffixaddress->count
- ) {
- return $narrowaddress->first;
- }
- return $suffixaddress->first;
- }
- =head2 $self->get_record_by_source_identifier($source_identifier)
- Return value: $DB_RECORD
- $self->get_record_by_source_identifier('nummeraanduiding-637372832372323')
- =cut
- sub get_record_by_source_identifier {
- my ($self, $source_identifier) = @_;
- die('Only call this method from a resultset object')
- unless UNIVERSAL::isa($self, 'DBIx::Class::ResultSet');
- my ($type, $id) = $source_identifier =~ /^(.+)\-(.+)$/;
- die "Need valid source_identifier (got: '$source_identifier')" unless $type && $id;
- die('Type: ' . $type . ' unsupported') unless SOURCE_TABLES()->{$type};
- return $self
- ->result_source
- ->schema->resultset(
- SOURCE_TABLES()->{$type}
- )->search(
- {
- identificatie => $id
- }
- )->first;
- }
- =head2 $self->get_address_data_by_source_identifier($source_identifier)
- Return value: \%ADDRESS_DATA
- print Dumper($self->get_address_data_by_source_identifier('nummeraanduiding-9876543218375842'));
- $VAR1 = {
- 'huisletter' => 'A',
- 'huisnummer' => 23,
- 'huisnummertoevoeging' => '1rec',
- 'postcode' => '1051JL',
- 'straat' => 'Donker Curtiusstraat',
- 'woonplaats' => 'Amsterdam'
- };
- =cut
- sub get_address_data_by_source_identifier {
- my ($self, $source_identifier) = @_;
- die('Only call this method from a resultset object')
- unless UNIVERSAL::isa($self, 'DBIx::Class::ResultSet');
- my $record = $self->get_record_by_source_identifier($source_identifier)
- or return;
- my $rv = {};
- while ($record) {
- my ($record_name) = ref($record) =~ /::([^:]+)$/;
- my $structure = ESSENTIAL_DATA()->{ $record_name };
- for my $field (keys %{ $structure->{fields} }) {
- my $value = $structure->{fields}->{ $field };
- $rv->{ $value } = $record->$field;
- }
- if (defined($structure->{parent}) && $structure->{parent}) {
- my $parent = $structure->{parent}->{key};
- $record = $record->$parent;
- next;
- }
- $record = undef;
- }
- return $rv;
- }
- =head2 $self->get_human_identifier_by_source_identifier($source_identifier [,\%options ])
- Return value: \%ADDRESS_DATA
- print $self->get_human_identifier_by_source_identifier('nummeraanduiding-9876543218375842');
- # Returns: "Donker Curtiusstraat 23A-1rec"
- Gives a human readable string of the given BAG source identifier, you can
- influence the output by using one of the identifiers below
- B<Options>
- =over 4
- =item prefix_with_city BOOLEAN
- print $self->get_human_identifier_by_source_identifier(
- 'nummeraanduiding-9876543218375842'
- {
- prefix_with_city => 1,
- }
- );
- # Returns: "Amsterdam - Donker Curtiusstraat 23A-1rec"
- Prefix the output with the city name
- =back
- =cut
- sub get_human_identifier_by_source_identifier {
- my ($self, $source_identifier, $options) = @_;
- $options ||= {};
- die('Only call this method from a resultset object')
- unless UNIVERSAL::isa($self, 'DBIx::Class::ResultSet');
- my $record = $self->get_record_by_source_identifier($source_identifier)
- or return;
- my ($bagtype) = $source_identifier =~ /^(\w+)-\d+/;
- if (lc($bagtype) eq 'nummeraanduiding') {
- return (
- (
- defined($options->{prefix_with_city}) &&
- $options->{prefix_with_city}
- ) ? $record->openbareruimte->woonplaats->naam . ' - '
- : ''
- ) .
- $record->openbareruimte->naam . ' ' . $record->nummeraanduiding;
- }
- if (lc($bagtype) eq 'pand') {
- return 'Bouwjaar: ' . $record->bouwjaar;
- }
- if (lc($bagtype) eq 'verblijfsobject') {
- return 'Oppervlakte: ' . $record->oppervlakte;
- }
- if (lc($bagtype) eq 'standplaats') {
- return '-';
- }
- if (lc($bagtype) eq 'ligplaats') {
- return '-';
- }
- if (lc($bagtype) eq 'openbareruimte') {
- return $record->naam;
- #return $record->woonplaats->naam . ' > ' . $record->naam;
- }
- return '';
- }
- 1;