Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forward geo error: invalid type: sequence, expected a string #54

Closed
AppyCat opened this issue Jun 25, 2022 · 18 comments
Closed

Forward geo error: invalid type: sequence, expected a string #54

AppyCat opened this issue Jun 25, 2022 · 18 comments

Comments

@AppyCat
Copy link

AppyCat commented Jun 25, 2022

use geocoding::{Opencage, Forward, Point}; - using version 0.3.1 in cargo.toml

let oc: Opencage = Opencage::new("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".to_string());
let address = "Schwabing, München";
let res: Vec<Point> = oc.forward(&address).unwrap();
let first_result = &res[0];

The third line above responds with the error below:

thread 'main' panicked at 'called Result::unwrap() on an Err value: Error { kind: Json(Error("invalid type: sequence, expected a string", line: 1, column: 393)), url: None }', src/main.rs:91:53

Could it be due to a change in API with OpenCage? I tried OpenStreetMap too, which also responds with a type error. 3rd option not workable as it's limited to Switzerland vs being worldwide.

Use case is to get long lat by address (city, state, zip, country).

@freyfogle
Copy link
Contributor

Hi,

Ed from OpenCage here.

Can you establish at all what is causing the error, I mean which part of the response it is dying on?

The most recent change was over a month ago (see Change Log), which I suppose this could be related to.

Basically in the components portion of the response there can now be a key ISO_3166-2 which is a list of ISO 3166-2 codes for the location. Here is a detailed blog post describing the addition to the API.

I hope that helps.

@AppyCat
Copy link
Author

AppyCat commented Jun 25, 2022

Hi Ed, thank you for your quick response.

The line throwing the error is:

let res: Vec<Point> = oc.forward(&address).unwrap();

And the error is:

thread 'main' panicked at 'called Result::unwrap() on an Err value: Request(reqwest::Error { kind: Decode, source: Error("invalid type: sequence, expected a string", line: 1, column: 392) })', src/main.rs:91:53

I am trying to do a forward search to get longitude and latitude by an address which would typically be city, state, zip & country. I tried an ISO_3166-2 country code, but am still getting the above error over invalid type sequence.

Tried this code with the latest version of your library. Let me now if there's any more information I can share so we can figure ths out. Thanks again.

@freyfogle
Copy link
Contributor

sorry, I guess I am not formulating my question clearly. Yes, I see the error message, it was posted in the initial message in this thread. My question is which part of the JSON is causing this errror in the decoding? Which content is at "column 392"?
Please bear in mind I know nothing about Rust and am not the maintainer of this module.

Our API is returning:

     ...
      "components": {
        "ISO_3166-1_alpha-2": "DE",
        "ISO_3166-1_alpha-3": "DEU",
        "ISO_3166-2": [
          "DE-BY"
        ],
        "_category": "place",
        "_type": "neighbourhood",
        "city": "München",
        "city_district": "Schwabing-Freimann",
        "continent": "Europe",
        "country": "Deutschland",
        "country_code": "de",
        "political_union": "European Union",
        "postcode": "80805",
        "state": "Bayern",
        "state_code": "BY",
        "suburb": "Schwabing"
      },

my guess is it is the newly-added ISO_3166-2 that is causing problems as Rust is expecting the value to be a string, not a list. Please see the blog post to understand why it needs to be a list (in short: many countries have multiple ISO 3166-2 codes).

@b4l
Copy link
Member

b4l commented Jun 25, 2022

@freyfogle this seems to be the issue indeed as components is defined as a HashMap<String, String> https://github.com/georust/geocoding/blob/master/src/opencage.rs#L535.

@AppyCat
Copy link
Author

AppyCat commented Jun 25, 2022

Hi Ed, I'm not feeding or getting any json.

Thanks for the update Balthasar. What would you recommend I try to resolve this or will it require a update in the crate ref the type issue?

@b4l
Copy link
Member

b4l commented Jun 25, 2022

Probably can test this by replacing the String value with something like HashMap<String, Component>

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Component {
    String(String),
    List(Vec<String>),
}

or HashMap<String, serde_json::Value>

@freyfogle
Copy link
Contributor

Hi Ed, I'm not feeding or getting any json.

yes, you are getting back JSON when you query our API

Please see pur demo page: https://opencagedata.com/demo
Put in the query "Schwabing, München" and you can see exactly the JSON we are returning.

Bildschirmfoto 2022-06-25 um 13 08 18

@urschrei
Copy link
Member

or HashMap<String, serde_json::Value>

That seems to work. @b4l would you like to push a PR with the fix?

@b4l
Copy link
Member

b4l commented Jun 25, 2022

@urschrei yes, I can do that.

@AppyCat
Copy link
Author

AppyCat commented Jun 25, 2022

You guys are awesome, thank you fo the refactor :)

Ed, thanks for your help, you're a gentleman & scholar.

On slightly diff point, in Postgres do you have a preference on radius search by distance. Options are:

PostGiS geometry
PostGIS geography
Cube EarthDistance

@urschrei
Copy link
Member

v0.4.0 is on crates.io, with the fix. Thanks @freyfogle and @b4l for the diagnosis and PR

@AppyCat
Copy link
Author

AppyCat commented Jun 25, 2022

Just tried v0.4.0. Am getting this error now trying it in async main function in Actix Web:

thread 'main' panicked at 'Cannot drop a runtime in a context where blocking is not allowed. This happens when a runtime is dropped from within an asynchronous context.', /Users/test/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.19.2/src/runtime/blocking/shutdown.rs:51:21

@urschrei
Copy link
Member

That error doesn't originate in geocoding I'm afraid.

@AppyCat
Copy link
Author

AppyCat commented Jun 25, 2022

That's a good thing. Seems to be a Tokio issue, will test again. Is it possible to run gecoding async?

@b4l
Copy link
Member

b4l commented Jun 25, 2022

@AppyCat this seems to be expected, resulting from how the blocking reqwest Client interacts with the tokio runtime: seanmonstar/reqwest#1017

@AppyCat
Copy link
Author

AppyCat commented Jun 25, 2022

I got it working by spawning a new thread, so that's a workable solution:

thread::spawn(move || {
let oc: Opencage = Opencage::new("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".to_string());
let address = "Schwabing, München";
let res: Vec<Point> = oc.forward(address).unwrap();
println!("lon {} lat {}", res[0].x(), res[0].y());
});

Are there any key differences between Opencage and Openstreetmap?

Perhaps it may be an idea to address in the docs how the Client interacts with the Tokio runtime, with a suggestion or an example of working around that. Thanks again.

@freyfogle
Copy link
Contributor

Hi yes, there are many differences between OpenStreetMap and OpenCage.
I dont think the rust SDK is really the place for the discussion

Spend some time reading the OpenCage geocoding API docs.

@AppyCat
Copy link
Author

AppyCat commented Jun 25, 2022

Thanks, Geocoding resolves the current use case. Will check docs on both APIs in a few days.

@AppyCat AppyCat closed this as completed Jun 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants