Geo-Location-TimeZoneFinder

 view release on metacpan or  search on metacpan

TimeZoneFinder.xs  view on Meta::CPAN


        /* Read the time zones. */
        dbf_fh = dbf_init_file(&self->dbf_fh, self->dbf_stream, self);
        if (dbf_read(dbf_fh, handle_dbf_header, handle_dbf_record) < 0) {
            croak("Error reading \"%" SVf "\": %s",
                  SVfARG(self->dbf_filename), dbf_fh->error);
        }

        /* The time zone file is no longer needed. */
        (void) fclose(self->dbf_stream);
        self->dbf_stream = NULL;

        expected_size = self->index.num_entries;

        if (self->dbf_num != expected_size) {
            croak("Expected %zu records, got %zu in \"%" SVf "\"",
                  expected_size, self->dbf_num, SVfARG(self->dbf_filename));
        }

        /* Index the shapes by their bounding boxes. */
        shp_fh = shp_init_file(&self->shp_fh, self->shp_stream, self);
        if (shp_read(shp_fh, handle_shp_header, handle_shp_record) < 0) {
            croak("Error reading \"%" SVf "\": %s",
                  SVfARG(self->shp_filename), shp_fh->error);
        }

        if (self->shp_num != expected_size) {
            croak("Expected %zu records, got %zu in \"%" SVf "\"",
                  expected_size, self->shp_num, SVfARG(self->shp_filename));
        }
    } XCPT_TRY_END

    XCPT_CATCH {
        free_self(self);
        XCPT_RETHROW;
    }

    RETVAL = sv_bless(newRV_noinc(newSViv(PTR2IV(self))),
                      gv_stashsv(klass, GV_ADD));
  OUTPUT:
    RETVAL

void
time_zones_at(self, ...)
    Geo::Location::TimeZoneFinder self
  ALIAS:
    time_zone_at = 1
  INIT:
    SV *latitude = NULL;
    SV *longitude = NULL;
    NV lat = 0.0;
    NV lon = 0.0;
    I32 i;
    const char *key;
    SV *value;
    shp_point_t location;
    AV *time_zones;
    SSize_t tz_count, tz_num;
    SV **svp;
    U8 gimme = GIMME_V;
  PPCODE:
    if ((items - 1) % 2 != 0) {
        warn("Odd-length list passed to %s method",
             (ix == 1) ? "time_zone_at" : "time_zones_at");
    }

    for (i = 1; i < items; i += 2) {
        key = SvPV_nolen_const(ST(i));
        value = ST(i + 1);
        if (strEQ(key, "lat") || strEQ(key, "latitude")) {
            latitude = value;
        }
        else if (strEQ(key, "lon") || strEQ(key, "longitude")) {
            longitude = value;
        }
    }

    if (latitude == NULL) {
        croak("The \"latitude\" parameter is mandatory");
    }

    if (longitude == NULL) {
        croak("The \"longitude\" parameter is mandatory");
    }

    if (!looks_like_number(latitude)) {
        croak("The \"latitude\" parameter \"%" SVf "\" is not numeric",
              SVfARG(latitude));
    }

    if (!looks_like_number(longitude)) {
        croak("The \"longitude\" parameter \"%" SVf "\" is not numeric",
              SVfARG(longitude));
    }

    lat = SvNV(latitude);
    lon = SvNV(longitude);

    if (Perl_isnan(lat) || lat < -90.0 || lat > 90.0) {
        croak("The \"latitude\" parameter %" SVf " is not a number between "
              "-90 and 90", SVfARG(latitude));
    }

    if (Perl_isnan(lon) || lon < -180.0 || lon > 180.0) {
        croak("The \"longitude\" parameter %" SVf " is not a number between "
              "-180 and 180", SVfARG(longitude));
    }

    time_zones = newAV();

    location.x = lon;
    location.y = lat;
    get_special_time_zones(self, &location, time_zones);
    if (av_len(time_zones) < 0) {
        get_time_zones(self, &location, time_zones);
        if (av_len(time_zones) < 0) {
            get_time_zones_at_sea(self, &location, time_zones);
        }
    }

    tz_count = av_len(time_zones) + 1;



( run in 0.474 second using v1.01-cache-2.11-cpan-5511b514fd6 )