1.- INTRODUCTION AND BACKGROUND.
1.1.- INTRODUCTION
This case study demonstrates the use of Geospatial technologies to address a business challenge in the development of the pharmacy network in the Community of Madrid, Spain. This analysis is based on a project that includes legal, urban planning, engineering, administrative law and business considerations, but these aspects are outside the scope of this analysis. Here we focus exclusively on the application of advanced geospatial technologies, such as OSMnx and NetworkX, to overcome the geospatial challenges involved in the deployment of the pharmacy network, specifically how to find gaps in the urban pharmacy network where it is possible to install a new pharmacy while respecting the legal restrictions on the minimum distance between pharmacies.
1.2.- BACKGROUND
The pharmaceutical sector in Spain is regulated by the government with the aim of ensuring the supply and dispensing of medicines under appropriate quality and price conditions. Within this sector, distribution is affected by numerous limitations such as: the ownership, location and technical-economic conditions of pharmacies through state laws [1] and numerous regulations of the Autonomous Communities. This publication will deal with the limitations regarding location in the Autonomous Community of Madrid.
In relation to investment in the network of pharmacies in Spain in general, and in the Autonomous Community of Madrid in particular, the interesting problem of finding suitable locations for setting up a pharmacy arises. Although this search for locations can be in new urban areas under development, the most interesting is consolidated urban land. This is because the investment maturity period is shorter, as there is already a population living in the area, and the population density is usually higher than that planned for development areas. However, the problem is that in these consolidated urban areas there are already pharmacies in operation and the minimum distances between them must be respected by law.
The Spanish legal framework for the pharmaceutical sector establishes a minimum distance limitation of 250 m between pharmacies in order to locate a pharmacy office [2], [3]. This distance should be measured by following a route according to the following considerations:
- It should be a route similar to that which a pedestrian would follow.
- It should connect the centres of the fronts of pharmacies, not the entrances to pharmacies.
In addition, it must be ensured that the distance to public health facilities is more than 150 m measured along a pedestrian route.
Some issues are highlighted below:
- Pharmacies established prior to these laws do not follow these rules, with the result that some pharmacies are located at a distance of less than 250m. Despite this, there are still urban openings for the location of new pharmacies in areas of interest from the point of view of the pharmaceutical business.
- The existence of these urban openings is not enough and requires additional fieldwork to analyse the existence of available properties to house the pharmacy in these areas and to study the possibility offered by urban planning to actually establish a pharmacy in these areas. This is therefore a first step in the investment process.
The effectiveness of open-source tools such as OSMnx [4] and Networkx [5] in addressing complex problems related to urban fabric analysis, urban transport and mobility has been demonstrated in numerous publications [6]–[8]. The aim of this publication is to present a methodology based on OSMnx and NerworkX to reveal potential openings (opportunities) in the urban fabric for the location of pharmacies taking into account the legal restrictions.
NetworkX is a Python library designed for the application of graph theory [9] to analyse complex networks of relationships. It operates through a complicated framework of objects, where the basic elements are nodes, which are interconnected by edges, representing relationships between nodes. This tool is extensively employed in the study, analysis, and resolution of real-world problems, including but not limited to geospatial transportation networks, urban geospatial networks, and social networks. OSMnx is a specialized open-source python library that utilizes OpenStreetMap geospatial data to vectorize the street networks of cities globally as NetworkX graphs, facilitating their analysis through Python code. This approach is exemplified in [10], where various urban areas worldwide are systematically analyzed.
Given the numerous variables and alternatives to consider when employing these tools to address geospatial challenges, a broad selection of publications on the subject has been reviewed. Due to the innovative and rapidly evolving nature of these tools, some of these sources are exclusively available through online forums, such as https://ift.tt/Zdmtwu2, or in web-native scientific journals. A key issue that has prompted considerable debate in these sources is the method for connecting points of interest (POIs) to the city graphs of OSMnx, as discussed in [11] – [12], to enable computations over those graphs to solve problems related to the POIs. For the specific case addressed in this paper—the localization of pharmacy offices (POIs) in compliance with legal distance requirements—a new methodology has been developed to best suit the case, drawing on the relevant literature and online resources consulted. This methodology will be presented in the methodology section and is anticipated to be applicable to similar cases.
2.- METHOD
After collecting the necessary data: UTM coordinates of the pharmacies and the appropriate OSMnx graph of the city of Madrid, a first phase of this methodology consists of projecting the UTM coordinates of the pharmacies onto the OSMnx grid of Madrid as nodes. To do this, first, the edges of the OSMnx graph closest to each pharmacy will be identified in the “Data Placement on the Grid” phase of this methodology. This is done by importing the OSMnx graph without simplifying it. This way, all the curved lines of the Madrid urban graph can be approximated by several lines of reduced size, suitable for subsequent vector calculation. Furthermore, in this case it is necessary to project the UTM coordinates of the pharmacy offices, which are usually located inside their establishments, onto the OSMnx graph. This is done in the ‘Vector calculation’ phase of the methodology. In this way, the location of the midpoints of their façades on the public road is approximated.
Thirdly, once the UTM coordinates of the pharmacies have been projected as nodes of the OSMnx graph of the city of Madrid, in the subsequent ‘Grid Overlay’ phase, the areas of the network that are less than 250 m from each of the pharmacy-nodes are calculated. For this purpose, we do not consider the Euclidean distance but the topological distance, according to the walkable urban graph. Thus, n networks are obtained, one per pharmacy. Then, all of them are superimposed. Finally, the result of this superposition is subtracted from the OSMnx graph of Madrid. The result of this subtraction is a new network with the edges that are more than 250 m away from any pharmacy. Finally, this result is visualised as the final solution, since these edges constitute the axes on which a pharmacy office can be housed from the topological point of view.
To illustrate this publication and test the methodology, an urban area with a very complicated urban fabric has been selected, centred on the Madrid district of Tetuán, where pharmacies are also very close to each other, as some of them have been installed before the inclusion of the distance limitation in the legal framework.
To simplify the initial exposition of the methodology, the minimum legal distance condition of 150 m to health centres has been dispensed with, considering only the minimum distance between pharmacies as a limiting factor. Once the methodology has been explained in its entirety, it will be seen how this condition is easily introduced in the ‘discussion’ section.
Each phase of the methodology is explained in detail below.
2.1.- Data collection
The Community of Madrid has publicly available data on its pharmacies and health centres: addresses, codes, geographic coordinates, pharmacist in charge, etc. These data are available on the web [13]. The csv files used in this publication have been extracted from it [14]. Since the points to be considered for the calculation of distances should be the midpoints of the facades, and not the accesses to the pharmacies, it is a better approximation to use the UTM coordinates of the centre of the pharmacy establishments and project them onto the OSMnx graph, instead of geocoding the addresses of the pharmacies. In this way, the centre of the pharmacy establishments can be better approximated. This is particularly important in the case of pharmacy premises with long facades or corner facades, where the geolocation of the premises is assigned to the entrance and not to the middle point of the facade, which is the point referred to in the distance measurement regulation.
As for the OSMnx network to be considered, it will be of type ‘walk’ (network_type=’walk’
) [15], which includes all public pedestrian routes in Madrid. Since part of the methodology uses vector calculations, the default simplification of the OSMnx network is discarded (hence, simplify= ’False’
) in order to obtain the totality of the network nodes [16]. Thus, the curved parts of the network can be approximated by straight lines between the ‘nodes’ of the ‘edges’. With respect to this previous publication, in this case, in addition the centre of the pharmacy establishments should also be projected onto the OSMnx network. As a conclusion of the above discussion, the Madrid graph will be imported as follows in code 1:
Madrid_graph = ox.graph_from_place('Madrid, Spain', network_type='walk',
simplify= False )
Code 1. Python 3.11.5.
As explained above, the first step is to identify the edges of the detailed version of the OSMnx graph of Madrid that are closest to each pharmacy. This is done through the OSMnx distances module, saving the data of each nearest edge in the corresponding row of the pharmacies DataFrame, as well as the distance, as a check, code 2.2.2.- Data placement on the grid
Code 2. Python 3.11.5. ‘lon’ and ‘lat’ stand for the geographical coordinates Longitude and Latitude.for index, row in farmacias.iterrows():
edge = ox.distance.nearest_edges(Madrid_graph, row['lon'],
row['lat'], return_dist=True)
node = ox.distance.nearest_nodes(Madrid_graph, row['lon'],
row['lat'], return_dist=True)
farmacias.loc[index,'edge_1'] = str(edge[0][0])
farmacias.loc[index,'edge_2'] = str(edge[0][1])
farmacias.loc[index,'edge_n'] = str(edge[0][2])
farmacias.loc[index,'edge_d'] = edge[1]
farmacias.loc[index,'node'] = str(node[0])
farmacias.loc[index,'node_d'] = node[1]
Although not necessary for the subsequent calculations, the identification of the nearest node has also been included for information and quality control purposes.
These are shown below in Fig. 1 for the chosen Madrid pilot environment.

Fig. 1. Data Placement on the grid. UTM coordinates of the pharmacies, blue points. Nearest nodes of the graph, red points. Closest edges of the graph, red segments. Own elaboration using OSMnx. Data © OpenStreetMap contributors, available under the Open Database License
In order to project the pharmacies on the graph of Madrid, it is taken into account that what is of interest in this case is to identify the midpoint of their façade on the public ways, i.e. on the graph. As mentioned above, in most cases, the UTM provided in the Public Administration files refer to a point inside the commercial establishment. Therefore, it is necessary to project these points on the Madrid graph, transforming them into a new node of the graph. In this case, it is not correct to link pharmacies to the graph through an edge, since only pedestrian routes on public ways are of interest for distance measurement. So, instead, a new node should be created where each pharmacy office is projected on the graph, on the nearest edge determined in the previous section. The projection is performed using the Python library Numpy [17] using the following vector calculation, which provides the coordinates of the new P nodes that are the projection of each pharmacy on the graph, Fig. 2:2.3.- Vector calculation

In the case that “d” or “L2” is negative, which could occur due to small differences between the lengths of the edges in OSMnx and the projections made using UTM coordinates, the node where the pharmacy is projected will be one of the extreme nodes defining the edge, depending on which of the two quantities is negative. If “d” is negative, then the pharmacy will be projected as “E1”; if “L2” is negative, then as “E2”.
Thus, a new edge is created that connects this new node with the nodes of the nearest edge. Subsequently, the previously determined nearest edge is deleted, as it is replaced by the one just created. See code 3.
for index, row in farmacias.iterrows():
# vector calculation
F = np.array( [row['localizacion_coordenada_x'], row['localizacion_coordenada_y']])
E1 = np.array([utm.from_latlon(Madrid_graph.nodes[row['edge_1']]['y'], Madrid_graph.nodes[row['edge_1']]['x'], 30,'N')[0],
utm.from_latlon(Madrid_graph.nodes[row['edge_1']]['y'], Madrid_graph.nodes[row['edge_1']]['x'], 30,'N')[1]])
E2 = np.array([utm.from_latlon(Madrid_graph.nodes[row['edge_2']]['y'], Madrid_graph.nodes[row['edge_2']]['x'], 30,'N')[0],
utm.from_latlon(Madrid_graph.nodes[row['edge_2']]['y'], Madrid_graph.nodes[row['edge_2']]['x'], 30,'N')[1]])
d = np.dot(E2-E1,F-E1)/Madrid_graph.edges[(row['edge_1'],row['edge_2'],row['edge_n'] )]['length']
d_vect = (E2-E1)*d/Madrid_graph.edges[(row['edge_1'],row['edge_2'],row['edge_n'] )]['length']
F_coord = E1 + d_vect
L_calculada = np.sqrt(np.dot(E2-E1,E2-E1))
F_coord_LL = utm.to_latlon(F_coord[0], F_coord[1], 30, 'N')
L2 = Madrid_graph.edges[(row['edge_1'],row['edge_2'],row['edge_n'] )]['length'] - d
# edge and node substitution
if d<0:
nx.relabel_nodes(Madrid_graph, {row['edge_1']: row['farmacia_nro_soe']}, copy= False)
nx.set_node_attributes(Madrid_graph, { row['farmacia_nro_soe'] :{'color':'r', 'size':10 }} )
elif L2<0:
nx.relabel_nodes(Madrid_graph, {row['edge_2']: row['farmacia_nro_soe']}, copy=False)
nx.set_node_attributes(Madrid_graph, { row['farmacia_nro_soe'] :{'color':'r', 'size':10 }} )
else:
Madrid_graph.add_edge(row['edge_1'],row['farmacia_nro_soe'],0)
nx.set_edge_attributes(Madrid_graph, { (row['edge_1'], row['farmacia_nro_soe'],
0):{'length':d, 'osmid' : row['farmacia_nro_soe'], 'color':'r', 'size':4 }})
Madrid_graph.add_edge(row['farmacia_nro_soe'],row['edge_2'],0)
nx.set_edge_attributes(Madrid_graph, { (row['farmacia_nro_soe'], row['edge_2'],
0):{'length':L2 , 'osmid' : row['farmacia_nro_soe'], 'color':'r', 'size':4 }})
Madrid_graph.remove_edge(row['edge_1'],row['edge_2'],row['edge_n'] )
nx.set_node_attributes(Madrid_graph,
{ row['farmacia_nro_soe'] :{'x':F_coord_LL[1], 'y':F_coord_LL[0], 'color':'r', 'size':10 }} )
Code 3. . Python 3.11.5. ‘farmacia_nro_soe’ stands for pharmacy code. The variables in the beginning (F, E1, E2, d, etc) refer to those in Fig. 2. The other attributes of nodes and edges (‘color’, ‘size’) are intended to highlight them in the drawing process.
The result of this calculation is shown in Fig. 3

3.- RESULTS
Fig. 4 shows the result of applying the procedure to the set of pharmacies represented by the green dots only in an almond-shaped area of the city of Madrid. All edges containing points that are less than 250 m away from the given pharmacy network have been removed, so that a gap is observed within the illustration. The edges that are still present within the gap after the removal are those where it would be possible to house a new pharmacy from a topological point of view. Obviously, in the actual project it is necessary to check the urban conditions of these ‘edges’, as well as the availability of a commercial real estate to house a pharmacy, see the following section.

In cases different from the one at hand, in which not only public roads are useful for the work, but also non-public ones, a graph that includes all of them—both public and non-public—could be selected by using the Overpass QL code to specify a custom filter [18], code 6:
Madrid_graph = ox.graph_from_place('Madrid, Spain', simplify= False,
custom_filter=
'["area"!~"yes"]'
'["highway"!~"cycleway|motor|proposed|construction|abandoned|platform|raceway"]'
'["foot"!~"no"]["service"!~"private"]["access"!~"private"]' )
5.- Data Availability and Disclaimer
The datasets utilized in this study are publicly accessible and licensed for any use by the Autonomous Community of Madrid, Spain. Street network data was sourced from OpenStreetMap © OpenStreetMap contributors, via the OSMnx Python library, and is available under the Open Database License (ODbL): https://opendatacommons.org/licenses/odbl/1.0/ . Geospatial layers as pharmacy locations, were derived from publicly accessible GeoJSON and csv files hosted on https://datos.comunidad.madrid/group/salud and https://datos.comunidad.madrid/catalogo/dataset/6f407280-6ab1-43fb-bb48-ab954ec6edae/resource/130c1f6e-b131-44a1-94c9-00c9bb807ca6/download/oficinas_farmacia.csv , by the Autonomous Community of Madrid, Spain, explicitly permitting any use, as can be seen in the corresponding Terms of Use and Licensing Information at https://www.comunidad.madrid/servicios/012-atencion-ciudadano/aviso-legal-privacidad.
The methodological design, technical implementation (e.g., network analysis via NetworkX), and spatial computations presented in this article were developed independently by the author. All analytical workflows, visualizations, and conclusions are original contributions, free from third-party intellectual property restrictions. For transparency, direct links to data sources has been provided in the References and Data Availability sections of this article.
Note on Liability:
In accordance with the publicly available data sources employed, as explained in the previous “Data Availability” section, the author hereby disclaims any responsibility for consequences, damages, or losses resulting from the access, use, or interpretation of the information presented in this work, as done in the Terms of Use of such data sources. This article is intended strictly for educational purposes and does not constitute professional or commercial advice. Users are urged to independently validate data and consult relevant experts before applying any findings.
6.- REFFERENCES
[1] Jefatura del Estado de España, “Ley 29/2006, de 26 de julio, de garantías y uso racional de los medicamentos y productos sanitarios.,” BOE, vol. 178, no. BOE-A-2006-13554, pp. 28122–28165, 2006.
[2] Jefatura del Estado de España, “Ley 16/1997, de 25 de abril, de Regulación de Servicios de las Oficinas de Farmacia.,” BOE, vol. 100, no. BOE-A-1997-9022, pp. 13450–13452, 1997.
[3] Ministerio de Sanidad y Seguridad Social de España, “ORDEN de 21 de noviembre de 1979 por la que se desarrolla el Real Decreto 909/1978, de 14 de abril, en lo referente al establecimiento, transmisión e integración de Oficinas de Farmacia.,” BOE, vol. 302, no. BOE-A-1979-29679, pp. 28975–28977, 1979.
[4] G. Boeing, “Modeling and Analyzing Urban Networks and Amenities with OSMnx. Working paper.,” github.com, 2024. [Online]. Available: https://geoffboeing.com/publications/osmnx-paper/. [Accessed: 28-Jun-2024].
[5] A. A. Hagberg, D. A. Schult, and P. J. Swart, “Exploring network ntructure, nynamics, and nunction using NetworkX,” in Proceedings of the 7th Python in Science Conference, 2008, no. SciPy.
[6] P. Zhao, Y. Yen, E. Bailey, and M. T. Sohail, “Analysis of urban drivable and walkable street networks of the ASEAN smart cities network,” ISPRS Int. J. Geo-Information, vol. 8, no. 10, 2019.
[7] G. Boeing, “Urban street network analysis in a computational notebook,” Region, vol. 6, no. 3, 2019.
[8] G. Boeing, “Street Network Models and Indicators for Every Urban Area in the World,” in Geographical Analysis, 2022, vol. 54, no. 3.
[9] S. Ghosh, A. Mallick, A. Chowdhury, K. De Sarkar, and J. Mukherjee, “Graph theory applications for advanced geospatial modelling and decision-making,” Appl. Geomatics, vol. 16, no. 4, pp. 799–812, 2024.
[10] G. Boeing, “A multi-scale analysis of 27,000 urban street networks: Every US city, town, urbanized area, and Zillow neighborhood,” Environ. Plan. B Urban Anal. City Sci., vol. 47, no. 4, 2020.
[11] D. Vityazev, “Connecting Data Points to a Road Graph with Python Efficiently,” Towards Data Science, 2022. [Online]. Available: https://towardsdatascience.com/connecting-datapoints-to-a-road-graph-with-python-efficiently-cb8c6795ad5f.
[12] Y. Chang, “Connecting and interpolating POIs to a road network,” Towards Data Science, 2019. [Online]. Available: https://towardsdatascience.com/connecting-pois-to-a-road-network-358a81447944. [Accessed: 07-Oct-2024].
[13] Comunidad de Madrid, “Datos Abiertos Comunidad de Madrid. Portal de transparencia,” 2024. [Online]. Available: https://datos.comunidad.madrid/group/salud. [Accessed: 01-Oct-2024].
[14] Comunidad de Madrid, “Oficinas de Farmacia, csv files.,” Portal de Datos Abiertos Comunidad de Madrid. Portal de transparencia, 2024. [Online]. Available: https://datos.comunidad.madrid/catalogo/dataset/6f407280-6ab1-43fb-bb48-ab954ec6edae/resource/130c1f6e-b131-44a1-94c9-00c9bb807ca6/download/oficinas_farmacia.csv.
[15] G. Boeing, “OSMnx: New methods for acquiring, constructing, analyzing, and visualizing complex street networks,” Comput. Environ. Urban Syst., vol. 65, pp. 126–139, 2017.
[16] M. A. Alattar, C. Cottrill, and M. Beecroft, “Modelling cyclists’ route choice using Strava and OSMnx: A case study of the City of Glasgow,” Transp. Res. Interdiscip. Perspect., vol. 9, 2021.
[17] C. R. Harris et al., “Array programming with NumPy,” Nature, vol. 585, no. 7825. 2020.
[18] G. Boeing, “Use string formatting to insert infrastructure into query,” github, 2017. [Online]. Available: https://github.com/gboeing/osmnx/blob/v0.5.3/osmnx/core.py#L482-483. [Accessed: 01-Sep-2024].
[19] Comunidad de Madrid, “Centros de Salud, csv files.,” Portal de Datos Abiertos de la Comunidad de Madrid. Portal de transparencia, 2024. [Online]. Available: https://datos.comunidad.madrid/dataset/centros_servicios_establecimientos_sanitarios.
[20] A. Vybornova, T. Cunha, A. Gühnemann, and M. Szell, “Automated Detection of Missing Links in Bicycle Networks,” Geogr. Anal., vol. 55, no. 2, 2023.
The post Pharmacy Placement in Urban Spain appeared first on Towards Data Science.
from Artificial Intelligence – Techyrack Hub https://www.newstrenders.com/2025/05/08/pharmacy-placement-in-urban-spain/
via IFTTT
0 Comments