Skip to content

Commit

Permalink
Merge pull request #494 from YuukiToriyama/feature/chimei-ruiju/inclu…
Browse files Browse the repository at this point in the history
…de-latlng-data

chimei-ruiju.orgへの対応: 住所のパースに成功した場合に位置情報を`ParsedAddress`に含めるようにする
  • Loading branch information
YuukiToriyama authored Nov 2, 2024
2 parents 9ef5d15 + 5522921 commit 26027b3
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 31 deletions.
14 changes: 12 additions & 2 deletions core/src/domain/chimei_ruiju/entity.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::domain::common::latlng::LatLng;
use serde::Deserialize;

#[derive(Deserialize, Debug)]
Expand All @@ -17,7 +18,7 @@ pub struct CityMaster {
/// 町名リスト
pub(crate) towns: Vec<String>,
/// 緯度経度
coordinate: Coordinate,
pub(crate) coordinate: Coordinate,
}

#[derive(Deserialize, Debug)]
Expand All @@ -27,7 +28,7 @@ pub struct TownMaster {
/// 街区リスト
blocks: Vec<Block>,
/// 緯度経度
coordinate: Coordinate,
pub(crate) coordinate: Coordinate,
}

#[allow(dead_code)]
Expand All @@ -51,3 +52,12 @@ pub struct Coordinate {
/// 経度
pub(crate) longitude: f64,
}

impl Coordinate {
pub(crate) fn to_lat_lng(&self) -> LatLng {
LatLng {
latitude: self.latitude,
longitude: self.longitude,
}
}
}
64 changes: 43 additions & 21 deletions core/src/experimental/parse_with_chimeiruiju.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
use crate::domain::common::latlng::LatLng;
use crate::domain::common::token::Token;
use crate::experimental::parser::Parser;
use crate::interactor::chimei_ruiju::{ChimeiRuijuInteractor, ChimeiRuijuInteractorImpl};
use crate::tokenizer::Tokenizer;
use std::option::Option;

impl Parser {
pub(crate) async fn parse_with_chimeiruiju(&self, address: &str) -> Vec<Token> {
pub(crate) async fn parse_with_chimeiruiju(
&self,
address: &str,
) -> (Vec<Token>, Option<LatLng>) {
let interactor = ChimeiRuijuInteractorImpl::default();
let tokenizer = Tokenizer::new(address);
let mut lat_lng: Option<LatLng> = None;

// 都道府県名の検出
let (prefecture, tokenizer) = match tokenizer.read_prefecture() {
Expand All @@ -15,20 +21,24 @@ impl Parser {
if self.options.verbose {
log::error!("都道府県名の検出に失敗しました")
}
return not_found.tokens;
return (not_found.tokens, lat_lng);
}
};

// 市区町村名の検出
// 都道府県マスタの取得
let prefecture_master = match interactor.get_prefecture_master(&prefecture).await {
Ok(result) => result,
Ok(result) => {
lat_lng.replace(result.coordinate.to_lat_lng());
result
}
Err(error) => {
if self.options.verbose {
log::error!("{}", error)
}
return tokenizer.finish().tokens;
return (tokenizer.finish().tokens, lat_lng);
}
};
// 市区町村名の検出
let (city_name, tokenizer) = match tokenizer.read_city(&prefecture_master.cities) {
Ok(found) => found,
Err(not_found) => {
Expand All @@ -40,39 +50,51 @@ impl Parser {
if self.options.verbose {
log::error!("市区町村名の検出に失敗しました")
}
return not_found.tokens;
return (not_found.tokens, lat_lng);
}
}
} else {
if self.options.verbose {
log::error!("市区町村名の検出に失敗しました")
}
return not_found.finish().tokens;
return (not_found.finish().tokens, lat_lng);
}
}
};

// 町名の検出
// 市区町村マスタの取得
let city_master = match interactor.get_city_master(&prefecture, &city_name).await {
Ok(result) => result,
Ok(result) => {
lat_lng.replace(result.coordinate.to_lat_lng());
result
}
Err(error) => {
if self.options.verbose {
log::error!("{}", error)
}
return tokenizer.finish().tokens;
return (tokenizer.finish().tokens, lat_lng);
}
};
let (_, tokenizer) = match tokenizer.read_town(city_master.towns) {
// 町名の検出
let (town_name, tokenizer) = match tokenizer.read_town(city_master.towns) {
Ok(found) => found,
Err(not_found) => {
if self.options.verbose {
log::error!("町名の検出に失敗しました")
}
return not_found.tokens;
return (not_found.tokens, lat_lng);
}
};

tokenizer.finish().tokens
// 町村マスタの取得
if let Ok(town_master) = interactor
.get_town_master(&prefecture, &city_name, &town_name)
.await
{
lat_lng.replace(town_master.coordinate.to_lat_lng());
};

(tokenizer.finish().tokens, lat_lng)
}
}

Expand All @@ -90,11 +112,11 @@ mod tests {
verbose: false,
},
};
let result = parser
let (tokens, _) = parser
.parse_with_chimeiruiju("奈川県横浜市磯子区洋光台3-10-3")
.await;
assert_eq!(
result,
tokens,
vec![Token::Rest("奈川県横浜市磯子区洋光台3-10-3".to_string())]
)
}
Expand All @@ -108,11 +130,11 @@ mod tests {
verbose: false,
},
};
let result = parser
let (tokens, _) = parser
.parse_with_chimeiruiju("神奈川県横浜県磯子市洋光台3-10-3")
.await;
assert_eq!(
result,
tokens,
vec![
Token::Prefecture(Prefecture {
prefecture_name: "神奈川県".to_string(),
Expand All @@ -132,11 +154,11 @@ mod tests {
verbose: false,
},
};
let result = parser
let (tokens, _) = parser
.parse_with_chimeiruiju("神奈川県横浜市磯子区陽光台3-10-3")
.await;
assert_eq!(
result,
tokens,
vec![
Token::Prefecture(Prefecture {
prefecture_name: "神奈川県".to_string(),
Expand All @@ -160,11 +182,11 @@ mod tests {
verbose: false,
},
};
let result = parser
let (tokens, _) = parser
.parse_with_chimeiruiju("神奈川県横浜市磯子区洋光台3-10-3")
.await;
assert_eq!(
result,
tokens,
vec![
Token::Prefecture(Prefecture {
prefecture_name: "神奈川県".to_string(),
Expand Down
23 changes: 18 additions & 5 deletions core/src/experimental/parser.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::domain::common::latlng::LatLng;
use crate::domain::common::token::Token;
use serde::Serialize;

Expand Down Expand Up @@ -87,11 +88,12 @@ impl Parser {
/// }
/// ```
pub async fn parse(&self, address: &str) -> ParsedAddress {
let tokens = match self.options.data_source {
DataSource::ChimeiRuiju => self.parse_with_chimeiruiju(address).await,
DataSource::Geolonia => self.parse_with_geolonia(address).await,
};
ParsedAddress::from(tokens)
match self.options.data_source {
DataSource::ChimeiRuiju => {
ParsedAddress::from(self.parse_with_chimeiruiju(address).await)
}
DataSource::Geolonia => ParsedAddress::from(self.parse_with_geolonia(address).await),
}
}
}

Expand Down Expand Up @@ -184,6 +186,17 @@ impl From<Vec<Token>> for ParsedAddress {
}
}

impl From<(Vec<Token>, Option<LatLng>)> for ParsedAddress {
fn from((tokens, lat_lng): (Vec<Token>, Option<LatLng>)) -> Self {
let mut parsed_address = ParsedAddress::from(tokens);
if let Some(lat_lng) = lat_lng {
parsed_address.metadata.longitude = Some(lat_lng.longitude);
parsed_address.metadata.latitude = Some(lat_lng.latitude);
}
parsed_address
}
}

#[cfg(test)]
mod tests {
use crate::domain::common::latlng::LatLng;
Expand Down
1 change: 0 additions & 1 deletion core/src/interactor/chimei_ruiju.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl {
CityMasterRepository::get(&self.api_service, prefecture, city_name).await
}

#[allow(dead_code)]
async fn get_town_master(
&self,
prefecture: &Prefecture,
Expand Down
2 changes: 0 additions & 2 deletions core/src/repository/chimei_ruiju/town.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ use crate::domain::chimei_ruiju::error::ApiError;
use crate::service::chimei_ruiju::ChimeiRuijuApiService;
use jisx0401::Prefecture;

#[allow(dead_code)]
pub struct TownMasterRepository {}

impl TownMasterRepository {
#[allow(dead_code)]
pub async fn get(
api_service: &ChimeiRuijuApiService,
prefecture: &Prefecture,
Expand Down

0 comments on commit 26027b3

Please sign in to comment.