
Quería crear una aplicación para el metro de Moscú tan pronto como Artemy Lebedev y su estudio dibujaran el esquema del metro en su forma actual.
1. Los datos de origen
Ahora el mapa oficial del metro se puede descargar en PDF
desde el sitio web oficial del Metro de Moscú . En el momento de la creación de la aplicación (mediados de 2013), el circuito estaba disponible como un archivo .ai (Adobe Illustrator) en el sitio web de Lebedev Studio. En cualquier caso, el siguiente paso es preparar los datos en Illustrator.
2. Preparación de datos
Abra PDF en Illustrator, active el modo de vista previa y
desmaye.horror horror
(se puede hacer clic)
Después de un trabajo largo y minucioso (aquí llegué con muchos años de experiencia en el periódico publicitario de Moscú, primero en el departamento de diseño y diseño, luego en el departamento de TI)
resultó lo siguiente
(se puede hacer clic)
Lo que se ha hecho:
- Se eliminaron numerosos restos, inscripciones, etc.
- cada línea de metro se dividió en secciones entre estaciones. Las líneas se rompieron bajo los dibujos de las estaciones, de modo que al dibujar las rutas construidas, no se veían juntas ni espacios.
- todas las "piezas" de líneas y todas las estaciones relacionadas con cada línea se agrupan en capas, en el orden que siguen.
3. Convertir gráficos a XAML
XAML usa
Microsoft Expression Design para traducir gráficos
. Aquí todo es simple: abra el archivo ai, exporte a XAML.
Diseño de expresiones de Microsoft:
(se puede hacer clic)
4. Comienza a programar (finalmente)
Actualmente, Visual Studio 2015 y MVVM-framework MVVM-light se utilizan para el desarrollo. Desafortunadamente, el archivo XAML obtenido en la etapa anterior no se puede usar directamente en la aplicación, a excepción de una capa estática con ríos y rutas "aeroexpress".
Por lo tanto, un poco más de trabajo se realiza manualmente, y en los recursos de la aplicación generamos el archivo XML final utilizado para representar el esquema de metro. Cuando se carga, se forman objetos de líneas de metro y estaciones de metro, se forman enlaces entre estaciones dentro de la misma línea, transiciones entre líneas, las líneas de anillo están "cerradas". Por cierto, las transiciones entre líneas se forman mediante programación. Entre dos estaciones, se dibujan líneas con un degradado de relleno, entre tres estaciones, se construyen arcos de un círculo construido en tres puntos, los centros de las estaciones que conforman la transición.
Un ejemplo de una capa de Vista responsable de representar arcos de transición entre tres estaciones (por brevedad, recursos responsables de la animación, etc.):
<ItemsControl x:Name="ArcCrossings" ItemsSource="{Binding CrossingArcTypeList}" Visibility="Visible" Height="1760" Width="1765"> <ItemsControl.ItemTemplate> <DataTemplate> <Grid x:Name="grid" Opacity="{Binding Dimmed, Converter={StaticResource BooleanToOpacityConverter}}"> <Path StrokeThickness="7.7" Stroke="{Binding CrossBrush}"> <Path.Data> <PathGeometry> <PathGeometry.Figures> <PathFigureCollection> <PathFigure StartPoint="{Binding GradientLineStartPoint}"> <PathFigure.Segments> <PathSegmentCollection> <ArcSegment Point="{Binding GradientLineEndPoint}" Size="{Binding ArcSize}" SweepDirection="Clockwise"/> </PathSegmentCollection> </PathFigure.Segments> </PathFigure> </PathFigureCollection> </PathGeometry.Figures> </PathGeometry> </Path.Data> </Path> <Path StrokeThickness="2.4" Stroke="{Binding SettingsVM.BackMainBrush, Source={StaticResource Locator}}"> <Path.Data> <PathGeometry> <PathGeometry.Figures> <PathFigureCollection> <PathFigure StartPoint="{Binding BlackLineStartPoint}"> <PathFigure.Segments> <PathSegmentCollection> <ArcSegment Point="{Binding BlackLineEndPoint}" Size="{Binding ArcSize}" SweepDirection="Clockwise"/> </PathSegmentCollection> </PathFigure.Segments> </PathFigure> </PathFigureCollection> </PathGeometry.Figures> </PathGeometry> </Path.Data> </Path> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl>
Para buscar rutas, se utiliza un algoritmo de onda con pequeñas variaciones. Por ejemplo, si se encuentra una ruta óptima que contiene dos o más transiciones, se construyen rutas adicionales en las que está prohibido utilizar líneas de metro "intermedias". El resultado es a veces opciones de viaje extremadamente paradójicas e inesperadas (ver capturas de pantalla a continuación).
Para buscar el automóvil necesario para una transición conveniente a otra línea de metro, se utilizó el siguiente enfoque: cada línea se estableció en la dirección "hacia adelante" y "hacia atrás". En consecuencia, es importante para nosotros desde qué lado nos acercamos a la estación de cruce, y a veces todavía es importante para nosotros en qué dirección iremos a lo largo de la línea que estamos cruzando.
Un fragmento de un archivo XML que describe la estación Kitay-Gorod de la línea Tagansko-Krasnopresnenskaya y su transición característica a la línea Kaluga-Riga:
<Station name="-" lat="55.755361" lon="37.632361" Width="16.8277" Height="16.8282" Canvas.Left="1011.71" Canvas.Top="741.034" Data="F1 M 1017.45,746.771C 1015.97,748.25 1015.97,750.646 1017.45,752.125C 1018.93,753.604 1021.33,753.603 1022.8,752.125C 1024.29,750.646 1024.28,748.25 1022.81,746.77C 1021.33,745.292 1018.93,745.292 1017.45,746.771 ZM 1014.2,755.425C 1010.91,752.15 1010.88,746.824 1014.15,743.524C 1017.43,740.225 1022.75,740.2 1026.05,743.473C 1029.35,746.744 1029.38,752.071 1026.1,755.371C 1022.83,758.672 1017.51,758.695 1014.2,755.425 Z " TextLabel.Left="2" TextLabel.Top="-15" ShowPad="1" IsCrossPlatform="true" CrossPlatformColor="FFF37025"> <transfers> <forward> <transfer LineID="400" station="-"> <forward vagons="11111"/> <backward vagons="00100"/> </transfer> </forward> <backward> <transfer LineID="400" station="-"> <forward vagons="00100"/> <backward vagons="11111"/> </transfer> </backward> </transfers> </Station>
1024.28,748.25 1022.81,746.77C 1021.33,745.292 1018.93,745.292 1017.45,746.771 ZM 1014.2,755.425C 1010.91,752.15 1010.88 <Station name="-" lat="55.755361" lon="37.632361" Width="16.8277" Height="16.8282" Canvas.Left="1011.71" Canvas.Top="741.034" Data="F1 M 1017.45,746.771C 1015.97,748.25 1015.97,750.646 1017.45,752.125C 1018.93,753.604 1021.33,753.603 1022.8,752.125C 1024.29,750.646 1024.28,748.25 1022.81,746.77C 1021.33,745.292 1018.93,745.292 1017.45,746.771 ZM 1014.2,755.425C 1010.91,752.15 1010.88,746.824 1014.15,743.524C 1017.43,740.225 1022.75,740.2 1026.05,743.473C 1029.35,746.744 1029.38,752.071 1026.1,755.371C 1022.83,758.672 1017.51,758.695 1014.2,755.425 Z " TextLabel.Left="2" TextLabel.Top="-15" ShowPad="1" IsCrossPlatform="true" CrossPlatformColor="FFF37025"> <transfers> <forward> <transfer LineID="400" station="-"> <forward vagons="11111"/> <backward vagons="00100"/> </transfer> </forward> <backward> <transfer LineID="400" station="-"> <forward vagons="00100"/> <backward vagons="11111"/> </transfer> </backward> </transfers> </Station>
5. Algunas capturas de pantalla de las rutas construidas (se puede hacer clic)
Ruta inesperada de Kievskaya-Koltsevaya a Kursk-Koltsevaya: Una ruta aún más inesperada desde el Jardín Alexander hasta Borovitskaya: De Okhotny Ryad a la Plaza de la Revolución: Es bastante común desde Shabolovskaya hasta Tula. Otra ruta desde Shabolovskaya a Tula en el modo ligero del esquema Vista general del circuito (modo de luz) Vista general del circuito (modo oscuro) Busque una estación (todo comienza con 'P') 6. Planes
En el momento del comienzo del desarrollo de la aplicación (le recuerdo que este es el comienzo o la mitad de 2013), se discutió Windows 8 - 8.1. En realidad, la aplicación sigue siendo "no UWP". En consecuencia, la aplicación todavía tiene "marcas de nacimiento" de Windows 8.1, en particular, la ubicación ambigua de la configuración de la aplicación. ¿Qué puedo decir? En Windows 10, el "encanto" de la configuración "a la Windows 8.1" parece un poco extraño. Con el tiempo, esto probablemente cambiará.
En la última actualización, tuve que "recortar" información sobre las salidas a la ciudad (es decir, ahora no hay ni idea de a qué automóvil entrar para que sea conveniente ingresar a la ciudad). Esto está en el futuro cercano.
Actualización
YouTube: demostración de la aplicación