def test_between_location_no_door_num(self): """Si no se especifica una altura en una una dirección de tipo 'between', el resultado final debería tener una posición calculada a partir del promedio de la posición de las dos intersecciones.""" resp_btwn = self.get_response({ 'direccion': 'Mar del Plata entre Diaz y 12 de Octubre', 'departamento': 'Río Hondo' }) point_btwn = Point.from_json_location(resp_btwn[0]['ubicacion']) resp_isct_1 = self.get_response({ 'direccion': 'Mar del Plata esquina Diaz', 'departamento': 'Río Hondo' }) point_isct_1 = Point.from_json_location(resp_isct_1[0]['ubicacion']) resp_isct_2 = self.get_response({ 'direccion': 'Mar del Plata esq. 12 de Octubre', 'departamento': 'Río Hondo' }) point_isct_2 = Point.from_json_location(resp_isct_2[0]['ubicacion']) midpoint = point_isct_1.midpoint(point_isct_2) distance = point_btwn.approximate_distance_meters(midpoint) self.assertAlmostEqual(distance, 0)
def test_intersection_position(self): """La posición de una intersección debería estar cerca a la posición de una altura sobre la primera calle cerca de la esquina.""" resp_simple = self.get_response({ 'direccion': 'Dr. Adolfo Guemes al 600', 'departamento': '66028' }) resp_isct = self.get_response({ 'direccion': 'Dr. Adolfo esq. Rivadavia', 'departamento': '66028' }) point_simple = Point.from_json_location(resp_simple[0]['ubicacion']) point_isct = Point.from_json_location(resp_isct[0]['ubicacion']) self.assertLess( point_simple.approximate_distance_meters(point_isct), 30 # metros )
def test_intersection_location_no_door_num(self): """Si no se especifica una altura en una intersección, se debería utilizar la posición de la intersección como campo 'ubicacion'.""" resp = self.get_response({ 'direccion': 'Maipú esquina Mendoza', 'departamento': 'Rosario' }) loc = resp[0]['ubicacion'] point_isct = Point.from_json_location(loc) point_target = Point(-60.636548, -32.952020) error_m = point_isct.approximate_distance_meters(point_target) self.assertTrue(error_m < 15, error_m)
def test_position(self): """Cuando sea posible, se debería georreferenciar la dirección utilizando los datos de la calle y la altura.""" resp = self.get_response({ 'direccion': 'Billinghurst nro 650', 'departamento': 'Comuna 5' }) point_resp = Point.from_json_location(resp[0]['ubicacion']) point_target = Point(-58.415413, -34.602319) error_m = point_resp.approximate_distance_meters(point_target) self.assertTrue(error_m < 15, error_m)
def run_location_queries(es, params_list, queries): """Dada una lista de queries de ubicación, construye las queries apropiadas a índices de departamentos y municipios, y las ejecuta utilizando Elasticsearch. Args: es (Elasticsearch): Conexión a Elasticsearch. params_list (list): Lista de ParametersParseResult. queries (list): Lista de queries de ubicación, generadas a partir de 'params_list'. Returns: list: Resultados de ubicaciones (QueryResult). """ # TODO: # Por problemas con los datos de origen, se optó por utilizar una # implementación simple para la la funcion 'run_location_queries'. # Cuando los datos de departamentos cubran todo el departamento nacional, # se podría modificar la función para que funcione de la siguiente forma: # # (Recordar que las provincias y departamentos cubren todo el territorio # nacional, pero no los municipios.) # # Por cada consulta, implementar un patrón similar al de address.py (con # iteradores de consultas), donde cada iterador ('búsqueda') realiza los # siguientes pasos: # # 1) Buscar la posición en el índice de departamentos. # 2) Si se obtuvo un departamento, buscar la posición nuevamente pero en el # índice de municipios. Si no se obtuvo nada, cancelar la búsqueda. # 3) Componer el departamento, la provincia del departamento y el municipio # en un QueryResult para completar la búsqueda. all_searches = [] state_searches = [] muni_searches = [] dept_searches = [] for query in queries: es_query = { 'geo_shape_geoms': [Point.from_json_location(query).to_geojson()], 'fields': [N.ID, N.NAME, N.SOURCE], 'size': 1 } # Buscar la posición en provincias, departamentos y municipios search = StatesSearch(es_query) all_searches.append(search) state_searches.append(search) search = DepartmentsSearch(es_query) all_searches.append(search) dept_searches.append(search) search = MunicipalitiesSearch(es_query) all_searches.append(search) muni_searches.append(search) # Ejecutar todas las búsquedas preparadas ElasticsearchSearch.run_searches(es, all_searches) locations = [] iterator = zip(params_list, queries, state_searches, dept_searches, muni_searches) for params, query, state_search, dept_search, muni_search in iterator: # Ya que la query de tipo location retorna una o cero entidades, # extraer la primera entidad de los resultados, o tomar None si # no hay resultados. state = state_search.result.hits[0] if state_search.result else None dept = dept_search.result.hits[0] if dept_search.result else None muni = muni_search.result.hits[0] if muni_search.result else None result = _build_location_result(params.received_values(), query, state, dept, muni) locations.append(result) return locations