diff --git a/assets/freeClassrooms/clock.svg b/assets/freeClassrooms/clock.svg
new file mode 100644
index 00000000..075e8225
--- /dev/null
+++ b/assets/freeClassrooms/clock.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/freeClassrooms/expand.svg b/assets/freeClassrooms/expand.svg
new file mode 100644
index 00000000..a8064ab6
--- /dev/null
+++ b/assets/freeClassrooms/expand.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/freeClassrooms/tick.svg b/assets/freeClassrooms/tick.svg
new file mode 100644
index 00000000..bae8dd33
--- /dev/null
+++ b/assets/freeClassrooms/tick.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/MainContainer.tsx b/src/MainContainer.tsx
index da440944..bd6e522d 100644
--- a/src/MainContainer.tsx
+++ b/src/MainContainer.tsx
@@ -65,7 +65,25 @@ export const MainContainer: FC = () => {
console.log("downloads")
}}
onNotifications={() => {
- console.log("notifications")
+ navigate("RoomDetails", {
+ room: {
+ name: "2.0.1",
+ capacity: 380,
+ building: "Edificio 2",
+ address: "Piazza Leonardo da Vinci, 32 - 20133 - Milano (MI)",
+ power: false,
+ },
+ startDate: "2023-02-22T16:15:00Z",
+ roomId: 32,
+ roomLatitude: 45.4788249919485,
+ roomLongitude: 9.227210008150676,
+ occupancies: {
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ "19:00": "FREE",
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ "19:35": "OCCUPIED",
+ },
+ })
}}
onSettings={() => {
navigate("SettingsNav", {
diff --git a/src/api/rooms.ts b/src/api/rooms.ts
index 10f35b54..8ff79e64 100644
--- a/src/api/rooms.ts
+++ b/src/api/rooms.ts
@@ -1,4 +1,4 @@
-import { HttpClient, RequestOptions } from "./HttpClient"
+import { AuthType, HttpClient, RequestOptions } from "./HttpClient"
/* eslint-disable @typescript-eslint/naming-convention */
export interface Rooms {
@@ -10,13 +10,32 @@ export interface Room {
building: string
power: boolean
link: string
- occupancyRate: number | undefined
+ occupancy_rate: number | null
+ occupancies: Occupancies
}
+
+export type Occupancies = Record<`${number}:${number}`, "FREE" | "OCCUPIED">
+
export interface RoomSimplified {
roomId: number
name: string
+ occupancies: Occupancies
occupancyRate: number | undefined
}
+
+export interface RoomDetails {
+ name: string
+ capacity: number
+ building: string
+ address: string
+ power: boolean
+}
+
+export interface OccupancyInfo {
+ room_id: number
+ occupancy_rate: null | number
+}
+
const client = HttpClient.getInstance()
/**
@@ -46,11 +65,36 @@ export const rooms = {
return response.data.free_rooms
},
+ async getOccupancyRate(roomId: number, options?: RequestOptions) {
+ const response = await client.poliNetworkInstance.get(
+ "/v1/rooms/" + roomId + "/occupancy",
+ {
+ ...options,
+ }
+ )
+ return response.data
+ },
+
+ async postOccupancyRate(
+ roomId: number,
+ rate: number,
+ options?: RequestOptions
+ ) {
+ const res = await client.poliNetworkInstance.post(
+ "/v1/rooms/" + roomId + "/occupancy",
+ {
+ ...options,
+ },
+ { params: { rate: rate }, authType: AuthType.POLINETWORK }
+ )
+ return res
+ },
+
/**
* Retrieves room details from PoliNetwork Server.
*/
async getRoomInfo(roomId: number, options?: RequestOptions) {
- const response = await client.poliNetworkInstance.get(
+ const response = await client.poliNetworkInstance.get(
"/v1/rooms/" + roomId,
{
...options,
diff --git a/src/components/ContentWrapperScroll.tsx b/src/components/ContentWrapperScroll.tsx
index a30aab87..2290a84b 100644
--- a/src/components/ContentWrapperScroll.tsx
+++ b/src/components/ContentWrapperScroll.tsx
@@ -1,5 +1,5 @@
import React, { FC } from "react"
-import { ScrollView, View } from "react-native"
+import { ScrollView, View, ViewStyle } from "react-native"
import { Text } from "components/Text"
import { NavBar, NavbarProps } from "components/NavBar"
import { usePalette } from "utils/colors"
@@ -21,7 +21,10 @@ export const ContentWrapperScroll: FC<{
* Props for the navbar, see {@link NavBar}
*/
navbarOptions?: NavbarProps
- marginTop?: number
+
+ style?: ViewStyle
+
+ scrollViewStyle?: ViewStyle
}> = props => {
const { background, isLight, primary } = usePalette()
@@ -56,23 +59,26 @@ export const ContentWrapperScroll: FC<{
)}
-
+
{props.children}
diff --git a/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderDynamic.tsx b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderDynamic.tsx
new file mode 100644
index 00000000..56d0ec3a
--- /dev/null
+++ b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderDynamic.tsx
@@ -0,0 +1,89 @@
+import React, { FC } from "react"
+import { View } from "react-native"
+import { usePalette } from "utils/colors"
+import Animated, {
+ runOnJS,
+ useAnimatedStyle,
+ useSharedValue,
+} from "react-native-reanimated"
+import {
+ Gesture,
+ GestureDetector,
+ GestureHandlerRootView,
+} from "react-native-gesture-handler"
+import { getCrowdStatus } from "utils/rooms"
+
+interface CrowdSliderDynamicProps {
+ usableWidth?: number
+ startingPos: number
+ onSlideEnd: (pos: number) => void
+}
+
+export const CrowdSliderDynamic: FC = props => {
+ const { sliderBorderColor } = usePalette()
+
+ const wrapper = (pos: number, width: number) => {
+ const crowdStatus = getCrowdStatus(pos, width)
+ if (props.onSlideEnd) {
+ props.onSlideEnd(crowdStatus)
+ }
+ }
+ const circleWidth = 28
+
+ //320 is modal width, 52 is content padding
+ const usableWidth = props.usableWidth ?? 320 - 52 - circleWidth
+
+ const startingPos = ((props.startingPos - 1) / 4) * usableWidth
+
+ const position = useSharedValue(startingPos)
+ const lastPosition = useSharedValue(startingPos)
+ const panGesture = Gesture.Pan()
+ .onUpdate(e => {
+ const newPos = e.translationX + lastPosition.value
+ position.value = newPos
+ if (newPos < 0) {
+ position.value = 0
+ } else if (newPos > usableWidth) {
+ position.value = usableWidth
+ }
+ })
+ .onEnd(() => {
+ lastPosition.value = position.value
+ runOnJS(wrapper)(position.value, usableWidth)
+ })
+
+ const animatedPos = useAnimatedStyle(() => ({
+ transform: [{ translateX: position.value }],
+ }))
+
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderLabels.tsx b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderLabels.tsx
new file mode 100644
index 00000000..7c5ea091
--- /dev/null
+++ b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderLabels.tsx
@@ -0,0 +1,49 @@
+import React, { FC } from "react"
+import { usePalette } from "utils/colors"
+import { BodyText } from "components/Text"
+import { View } from "react-native"
+
+export const CrowdSliderLabels: FC = () => {
+ const { labelsHighContrast } = usePalette()
+
+ return (
+
+
+ Basso
+
+
+ Medio
+
+
+ Alto
+
+
+ )
+}
diff --git a/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderStatic.tsx b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderStatic.tsx
new file mode 100644
index 00000000..931b908f
--- /dev/null
+++ b/src/components/FreeClass/ClassDetails/CrowdSlider/CrowdSliderStatic.tsx
@@ -0,0 +1,42 @@
+import React, { FC } from "react"
+import { Dimensions, View } from "react-native"
+import { usePalette } from "utils/colors"
+
+interface CrowdSliderStaticProps {
+ position: number
+}
+
+export const CrowdSliderStatic: FC = props => {
+ const { sliderBorderColor } = usePalette()
+
+ //56 is padding, 28 is circle diameter
+ const usableWidth = Dimensions.get("screen").width - 56 - 28
+
+ const startingPos = ((props.position - 1) / 4) * usableWidth
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/src/components/FreeClass/ClassDetails/CrowdingSection.tsx b/src/components/FreeClass/ClassDetails/CrowdingSection.tsx
new file mode 100644
index 00000000..4e8097a0
--- /dev/null
+++ b/src/components/FreeClass/ClassDetails/CrowdingSection.tsx
@@ -0,0 +1,145 @@
+import React, { FC, useEffect, useState } from "react"
+import { Pressable, View } from "react-native"
+import { usePalette } from "utils/colors"
+import { BodyText } from "components/Text"
+import { CrowdSliderStatic } from "./CrowdSlider/CrowdSliderStatic"
+import { CrowdSliderDynamic } from "./CrowdSlider/CrowdSliderDynamic"
+import { CrowdSliderLabels } from "./CrowdSlider/CrowdSliderLabels"
+import { ButtonCustom } from "components/Button"
+import { ModalWithGestures } from "../ModalWithGestures"
+import { api, RetryType } from "api"
+
+interface CrowdingSectionProps {
+ roomId: number
+ isSlidable?: boolean
+ onSlided?: () => void
+}
+
+export const CrowdingSection: FC = props => {
+ const { iconHighContrast, labelsHighContrast } = usePalette()
+
+ const [isModalVisible, setIsModalVisible] = useState(false)
+
+ const [occupancyRate, setOccupancyRate] = useState(1)
+
+ let occupancyRateUser = 3
+
+ const getOccupancyRate = async () => {
+ try {
+ const res = await api.rooms.getOccupancyRate(props.roomId)
+ if (res.occupancy_rate !== null) {
+ setOccupancyRate(res.occupancy_rate)
+ }
+ } catch (err) {
+ console.log(err)
+ }
+ }
+
+ useEffect(() => {
+ void getOccupancyRate()
+ }, [])
+
+ const postOccupancyRate = async () => {
+ try {
+ await api.rooms.postOccupancyRate(props.roomId, occupancyRateUser, {
+ retryType: RetryType.RETRY_N_TIMES,
+ maxRetries: 3,
+ })
+ } catch (err) {
+ console.log(err)
+ }
+ }
+ return (
+
+
+ Affollamento:
+
+
+
+
+
+
+ Se il dato sull'affollamento non è corretto
+
+ setIsModalVisible(true)}>
+
+ esprimi opinione
+
+
+
+
+ setIsModalVisible(false)}
+ >
+
+
+ Esprimi{"\n"}Opinione
+
+
+ Indica il livello di affollamento {"\n"} dell'aula
+
+
+ (occupancyRateUser = pos)}
+ />
+
+
+
+ {
+ void postOccupancyRate()
+ setIsModalVisible(false)
+ }}
+ />
+
+
+
+ )
+}
diff --git a/src/components/FreeClass/ClassDetails/InfoMapTile.tsx b/src/components/FreeClass/ClassDetails/InfoMapTile.tsx
new file mode 100644
index 00000000..91c18ac9
--- /dev/null
+++ b/src/components/FreeClass/ClassDetails/InfoMapTile.tsx
@@ -0,0 +1,241 @@
+import React, { FC } from "react"
+import { Linking, Platform, Pressable, View } from "react-native"
+import { usePalette } from "utils/colors"
+import { BodyText, Text } from "components/Text"
+import { extractBuilding, extractRoom } from "utils/rooms"
+import MapView from "react-native-maps"
+import expand from "assets/freeClassrooms/expand.svg"
+import { Canvas, ImageSVG, useSVG } from "@shopify/react-native-skia"
+
+interface InfoMapTileProps {
+ roomName: string
+ building: string
+ address?: string
+ capacity?: number
+ longitude?: number
+ latitude?: number
+}
+
+export const InfoMapTile: FC = props => {
+ const { labelsHighContrast, isLight, palette, primary } = usePalette()
+
+ const building = extractBuilding(props.building)
+ const roomName = extractRoom(props.roomName)
+
+ const expandSvg = useSVG(expand)
+
+ const latitude = props.latitude
+ const longitude = props.longitude
+
+ /*from https://stackoverflow.com/questions/73653813/how-to-open-google-map-with-latitude-and-longitude*/
+ const openAddressOnMap = (label: string, lat: string, lng: string) => {
+ const scheme = Platform.select({
+ ios: "maps:0,0?q=",
+ android: "geo:0,0?q=",
+ })
+ const latLng = `${lat},${lng}`
+ if (scheme) {
+ const url = Platform.select({
+ ios: `${scheme}${label}@${latLng}`,
+ android: `${scheme}${latLng}(${label})`,
+ })
+ if (url) {
+ void Linking.openURL(url)
+ }
+ }
+ }
+ return (
+
+
+
+
+ {building && roomName ? `${building}.` : undefined}
+
+
+ {building && roomName ? roomName : props.roomName}
+
+
+
+
+ Indirizzo :
+
+
+ {props.address}
+
+
+
+
+ Capienza:{" "}
+
+
+ {props.capacity}
+
+
+
+ {latitude && longitude && (
+
+
+
+ openAddressOnMap(
+ props.building,
+ latitude.toString(),
+ longitude.toString()
+ )
+ }
+ >
+
+ {expand && expandSvg && (
+
+
+
+ )}
+
+
+
+
+ consulta la{" "}
+
+
+ mappa
+
+
+
+
+
+ )}
+
+ )
+}
diff --git a/src/components/FreeClass/ClassDetails/RoomUtilsSection.tsx b/src/components/FreeClass/ClassDetails/RoomUtilsSection.tsx
new file mode 100644
index 00000000..0cef6ab4
--- /dev/null
+++ b/src/components/FreeClass/ClassDetails/RoomUtilsSection.tsx
@@ -0,0 +1,32 @@
+import React, { FC } from "react"
+import { View } from "react-native"
+import { usePalette } from "utils/colors"
+import { BodyText } from "components/Text"
+import { RoomUtilsTile } from "./RoomUtilsTile"
+
+interface RoomUtilsSectionProps {
+ power?: boolean
+ computers?: boolean
+ ribaltine?: boolean
+}
+
+export const RoomUtilsSection: FC = props => {
+ const { labelsHighContrast } = usePalette()
+
+ return (
+
+
+ Info Utili:
+
+
+
+
+
+ )
+}
diff --git a/src/components/FreeClass/ClassDetails/RoomUtilsTile.tsx b/src/components/FreeClass/ClassDetails/RoomUtilsTile.tsx
new file mode 100644
index 00000000..2619988e
--- /dev/null
+++ b/src/components/FreeClass/ClassDetails/RoomUtilsTile.tsx
@@ -0,0 +1,82 @@
+import React, { FC, useMemo } from "react"
+import { View } from "react-native"
+import { usePalette } from "utils/colors"
+import { BodyText } from "components/Text"
+
+import {
+ BlendMode,
+ Canvas,
+ Group,
+ ImageSVG,
+ Skia,
+ useSVG,
+} from "@shopify/react-native-skia"
+import tick from "assets/freeClassrooms/tick.svg"
+
+interface RoomUtilsTileProps {
+ name: string
+ status?: boolean
+}
+
+export const RoomUtilsTile: FC = props => {
+ const { palette, isLight, sliderBorderColor } = usePalette()
+
+ const tickSvg = useSVG(tick)
+
+ const paintTick = useMemo(() => Skia.Paint(), [])
+ paintTick.setColorFilter(
+ Skia.ColorFilter.MakeBlend(
+ Skia.Color(
+ props.status
+ ? isLight
+ ? palette.primary
+ : palette.lighter
+ : isLight
+ ? palette.lighter
+ : palette.primary
+ ),
+ BlendMode.SrcIn
+ )
+ )
+
+ return (
+
+ {tick && tickSvg && (
+
+
+
+ )}
+
+ {props.name}
+
+
+ )
+}
diff --git a/src/components/FreeClass/ClassDetails/TimeLeftTile.tsx b/src/components/FreeClass/ClassDetails/TimeLeftTile.tsx
new file mode 100644
index 00000000..9623804f
--- /dev/null
+++ b/src/components/FreeClass/ClassDetails/TimeLeftTile.tsx
@@ -0,0 +1,226 @@
+import React, { FC, useMemo } from "react"
+import { View } from "react-native"
+import { usePalette } from "utils/colors"
+import { BodyText } from "components/Text"
+
+import {
+ BlendMode,
+ Canvas,
+ Group,
+ ImageSVG,
+ Skia,
+ useSVG,
+} from "@shopify/react-native-skia"
+import clock from "assets/freeClassrooms/clock.svg"
+import { extractTimeLeft, getEndDate } from "utils/rooms"
+import { Occupancies } from "api/rooms"
+
+interface TimeLeftTileProps {
+ startDate: string
+ occupancies?: Occupancies
+}
+
+export const TimeLeftTile: FC = props => {
+ const { isLight, labelsHighContrast, iconHighContrast, primary } =
+ usePalette()
+
+ const clockSvg = useSVG(clock)
+
+ const paint = useMemo(() => Skia.Paint(), [])
+ paint.setColorFilter(
+ Skia.ColorFilter.MakeBlend(Skia.Color(labelsHighContrast), BlendMode.SrcIn)
+ )
+ const paintClock = useMemo(() => Skia.Paint(), [])
+ paintClock.setColorFilter(
+ Skia.ColorFilter.MakeBlend(
+ Skia.Color(isLight ? primary : "#fff"),
+ BlendMode.SrcIn
+ )
+ )
+
+ const now = new Date()
+
+ const startDate = new Date(props.startDate)
+
+ const endDate = getEndDate(startDate, props.occupancies)
+
+ const startHour = startDate.getHours().toString().padStart(2, "0")
+ const startMinutes = startDate.getMinutes().toString().padStart(2, "0")
+
+ const endhour = endDate?.getHours().toString().padStart(2, "0") ?? undefined
+ const endMinutes =
+ endDate?.getMinutes().toString().padStart(2, "0") ?? undefined
+
+ const { hoursLeft, minutesLeft } = extractTimeLeft(now, endDate)
+
+ return (
+
+
+ Libera:
+
+
+
+
+
+
+ Da
+
+
+
+ {startHour} : {startMinutes}
+
+
+
+
+
+ A
+
+
+
+ {endhour && endMinutes
+ ? `${endhour} : ${endMinutes}`
+ : "-- : --"}
+
+
+
+
+
+
+
+ {clock && clockSvg && (
+
+
+
+ )}
+
+
+ Mancano:
+
+
+ {hoursLeft && minutesLeft
+ ? `${hoursLeft} h ${minutesLeft}'`
+ : "-- h -- '"}
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/FreeClass/FreeClassList.tsx b/src/components/FreeClass/FreeClassList.tsx
index 9135f470..f33b905b 100644
--- a/src/components/FreeClass/FreeClassList.tsx
+++ b/src/components/FreeClass/FreeClassList.tsx
@@ -6,6 +6,8 @@ import { usePalette } from "utils/colors"
import timerIcon from "assets/freeClassrooms/timer.svg"
import overcrowdingIcon from "assets/freeClassrooms/overcrowding.svg"
import fireIcon from "assets/freeClassrooms/fire.svg"
+import { useNavigation } from "navigation/NavigationTypes"
+import { api } from "api"
import { FlatList } from "react-native-gesture-handler"
import { RoomSimplified } from "api/rooms"
@@ -13,6 +15,9 @@ const { width } = Dimensions.get("window")
interface FreeClassListProps {
data: RoomSimplified[] | undefined
+ date: Date
+ latitude?: number
+ longitude?: number
}
enum OvercrowdingTypes {
@@ -29,6 +34,7 @@ export const FreeClassList: FC = props => {
const timerSVG = useSVG(timerIcon)
const overcrowdingSVG = useSVG(overcrowdingIcon)
const fireSVG = useSVG(fireIcon)
+ const { navigate } = useNavigation()
const [isOvercrowded, setIsOvercrowded] = useState(false)
@@ -68,6 +74,22 @@ export const FreeClassList: FC = props => {
marginBottom: 34,
borderRadius: 12,
}}
+ onPress={async () => {
+ try {
+ const selectedRoom = await api.rooms.getRoomInfo(item.roomId)
+ navigate("RoomDetails", {
+ room: selectedRoom,
+ startDate: props.date.toISOString(),
+ roomId: item.roomId,
+ roomLatitude: props.latitude,
+ roomLongitude: props.longitude,
+ occupancies: item.occupancies,
+ occupancyRate: item.occupancyRate,
+ })
+ } catch (err) {
+ console.log(err)
+ }
+ }}
>
void
+}
+
+/**
+ * custom modal component that can use reanimated gestures!! The problem with standard modals is
+ * that gestures wrapped inside Pressable dont work. The content needs to use `gestureHandlerRootHOC`
+ * as implemented below.
+ *
+ */
+export const ModalWithGestures: FC = props => {
+ const { backgroundSecondary, modalBarrier } = usePalette()
+
+ const deleteSvg = useSVG(icon.svg)
+
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ const ContentRootHOC = gestureHandlerRootHOC(() => (
+
+
+ props.onClose()}
+ >
+
+
+
+
+
+ {props.children}
+
+
+
+ ))
+
+ return (
+ //TODO: animationType fade or slide?
+
+
+
+ )
+}
+
+const styles = StyleSheet.create({
+ pageWrapper: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ contentWrapper: {
+ borderRadius: 12,
+
+ shadowColor: "#000",
+ shadowOffset: {
+ width: 0,
+ height: 3,
+ },
+ shadowOpacity: 0.27,
+ shadowRadius: 4.65,
+ elevation: 6,
+ },
+ circle: {
+ width: 30,
+ height: 30,
+ backgroundColor: "#ffffff",
+ borderRadius: 15,
+ marginTop: 96,
+ marginBottom: 8,
+ justifyContent: "center",
+ alignItems: "center",
+ },
+})
diff --git a/src/components/FreeClass/PositionModality.tsx b/src/components/FreeClass/PositionModality.tsx
index e3a533ac..34f82ff7 100644
--- a/src/components/FreeClass/PositionModality.tsx
+++ b/src/components/FreeClass/PositionModality.tsx
@@ -128,7 +128,7 @@ export const PositionModality: FC = props => {
size="large"
/>
) : (
-
+
)}
) : (
diff --git a/src/components/FreeClass/buildingCoords.json b/src/components/FreeClass/buildingCoords.json
index a68f56c9..01597239 100644
--- a/src/components/FreeClass/buildingCoords.json
+++ b/src/components/FreeClass/buildingCoords.json
@@ -1,1165 +1,1215 @@
[
- {
- "acronym": "MIA",
- "campus": [
- {
- "name": ["Leonardo"],
- "buildings": [
- {
- "name": "Edificio 29",
- "address": "Piazza Leonardo da Vinci 26, Milano, 20133",
- "coords": {
- "latitude": 45.47668740966992,
- "longitude": 9.226326859295256
- }
- },
- {
- "name": "Edificio 1",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.47811790554435,
- "longitude": 9.227725945733395
- }
- },
- {
- "name": "Edificio 10",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.47912809822935,
- "longitude": 9.229883268245544
- }
- },
- {
- "name": "Edificio 2",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.4788249919485,
- "longitude": 9.227210008150676
- }
- },
- {
- "name": "Edificio 2A",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.47876288697592,
- "longitude": 9.227837695286086
- }
- },
- {
- "name": "Edificio 3",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.477435603580254,
- "longitude": 9.227835389634977
- }
- },
- {
- "name": "Edificio 3A",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.47729656843257,
- "longitude": 9.22805442460651
- }
- },
- {
- "name": "Edificio 4",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.478602838628646,
- "longitude": 9.22845329881462
- }
- },
- {
- "name": "Edificio 4A",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.478974667422236,
- "longitude": 9.228990510865588
- }
- },
- {
- "name": "Edificio 5",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.47769427270723,
- "longitude": 9.228464826976882
- }
- },
- {
- "name": "Edificio 6",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.47825202398337,
- "longitude": 9.22875994776181
- }
- },
- {
- "name": "Edificio 7",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.47814209083751,
- "longitude": 9.229737535377756
- }
- },
- {
- "name": "Edificio 8",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.478809769736515,
- "longitude": 9.229442414594473
- }
- },
- {
- "name": "Edificio 9",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.47759727192502,
- "longitude": 9.229230296528302
- }
- },
- {
- "name": "Edificio 9A",
- "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
- "coords": {
- "latitude": 45.4771381326113,
- "longitude": 9.229815926853346
- }
- }
- ]
- },
- {
- "name": ["Bassini"],
- "buildings": [
- {
- "name": "Edificio 19",
- "address": "Via Ponzio 34/3, Milano, 20133",
- "coords": {
- "latitude": 45.47879081655148,
- "longitude": 9.231155363015363
- }
- },
- {
- "name": "Edificio 20",
- "address": "Via Ponzio 34/5, Milano, 20133",
- "coords": {
- "latitude": 45.478695312571354,
- "longitude": 9.232531759044313
- }
- },
- {
- "name": "Edificio 21",
- "address": "Via Golgi 39, Milano, 20133",
- "coords": {
- "latitude": 45.479048844048855,
- "longitude": 9.233791065831895
- }
- },
- {
- "name": "Edificio 36",
- "address": "Via Golgi 39, Milano, 20133",
- "coords": {
- "latitude": 45.47839707102326,
- "longitude": 9.232902143392922
- }
- },
- {
- "name": "Edificio 36A",
- "address": "Via Golgi 39, Milano, 20133",
- "coords": {
- "latitude": 45.47840377309843,
- "longitude": 9.233573614377585
- }
- },
- {
- "name": "Edificio 37",
- "address": "Via Golgi 39, Milano, 20133",
- "coords": {
- "latitude": 45.47840377309843,
- "longitude": 9.233934440407387
- }
- },
- {
- "name": "Edificio 42",
- "address": "Via Bassini 34/3, Milano, 20133",
- "coords": {
- "latitude": 45.47751909234621,
- "longitude": 9.231437333034433
- }
- },
- {
- "name": "Edificio 43",
- "address": "Via Bassini 34/3, Milano, 20133",
- "coords": {
- "latitude": 45.477644758070845,
- "longitude": 9.231425385160406
- }
- },
- {
- "name": "Isola Ecologica",
- "address": "Via Bassini 2, Milano, 20133",
- "coords": {
- "latitude": 45.478764590939626,
- "longitude": 9.234032129716745
- }
- }
- ]
- },
- {
- "name": ["Bonardi"],
- "buildings": [
- {
- "name": "Edificio 11",
- "address": "Via Ampère 2, Milano, 20133",
- "coords": {
- "latitude": 45.479700368402455,
- "longitude": 9.227144319107985
- }
- },
- {
- "name": "Edificio 11B",
- "address": "Via Ampère 4, Milano, 20133",
- "coords": {
- "latitude": 45.48039066193507,
- "longitude": 9.226718974511959
- }
- },
- {
- "name": "Edificio 12",
- "address": "Via Bonardi 3, Milano, 20133",
- "coords": {
- "latitude": 45.479559627904706,
- "longitude": 9.227662857193996
- }
- },
- {
- "name": "Edificio 13",
- "address": "Via Bonardi 9, Milano, 20133",
- "coords": {
- "latitude": 45.47986624067945,
- "longitude": 9.228233965961486
- }
- },
- {
- "name": "Edificio 14",
- "address": "Via Bonardi 9, Milano, 20133",
- "coords": {
- "latitude": 45.47964507754049,
- "longitude": 9.22878834771603
- }
- },
- {
- "name": "Edificio 14A",
- "address": "Via Bonardi 9, Milano, 20133",
- "coords": {
- "latitude": 45.48014771978483,
- "longitude": 9.229170679933038
- }
- },
- {
- "name": "Edificio 14B",
- "address": "Via Bonardi 9, Milano, 20133",
- "coords": {
- "latitude": 45.48014771978483,
- "longitude": 9.228752504070686
- }
- },
- {
- "name": "Edificio 15",
- "address": "Via Ponzio 31, Milano, 20133",
- "coords": {
- "latitude": 45.47966685878651,
- "longitude": 9.229574518342371
- }
- },
- {
- "name": "Edificio 16A",
- "address": "Via Bonardi 9, Milano, 20133",
- "coords": {
- "latitude": 45.479556276937224,
- "longitude": 9.228453806990538
- }
- },
- {
- "name": "Edificio 16B",
- "address": "Via Bonardi 9, Milano, 20133",
- "coords": {
- "latitude": 45.48007902560742,
- "longitude": 9.227603117798322
- }
- },
- {
- "name": "Edificio 16C",
- "address": "Via Bonardi 9, Milano, 20133",
- "coords": {
- "latitude": 45.479629998198945,
- "longitude": 9.229118109245283
- }
- },
- {
- "name": "Edificio 18",
- "address": "Via Ponzio 33, Milano, 20133",
- "coords": {
- "latitude": 45.48018625550555,
- "longitude": 9.229739399120684
- }
- }
- ]
- },
- {
- "name": ["Colombo"],
- "buildings": [
- {
- "name": "Edificio 32.1",
- "address": "Via Colombo 40, Milano, 20133",
- "coords": {
- "latitude": 45.47213230193092,
- "longitude": 9.22686863256574
- }
- },
- {
- "name": "Edificio 32.2",
- "address": "Via Colombo 40, Milano, 20133",
- "coords": {
- "latitude": 45.47207569302287,
- "longitude": 9.227194415489148
- }
- },
- {
- "name": "Edificio 32.3",
- "address": "Via Colombo 40, Milano, 20133",
- "coords": {
- "latitude": 45.47184925682209,
- "longitude": 9.227171351211384
- }
- },
- {
- "name": "Edificio 32.4",
- "address": "Via Colombo 40, Milano, 20133",
- "coords": {
- "latitude": 45.47190990946507,
- "longitude": 9.226883047739344
- }
- },
- {
- "name": "Edificio 32.5",
- "address": "Via Colombo 40, Milano, 20133",
- "coords": {
- "latitude": 45.47175625597605,
- "longitude": 9.226926293260147
- }
- },
- {
- "name": "Edificio 30",
- "address": "Via Colombo 81, Milano, 20133",
- "coords": {
- "latitude": 45.47586392362531,
- "longitude": 9.226261178708338
- }
- }
- ]
- },
- {
- "name": ["Golgi"],
- "buildings": [
- {
- "name": "Edificio 26",
- "address": "Via Golgi 20, Milano, 20133",
- "coords": {
- "latitude": 45.47569395835836,
- "longitude": 9.235024035751083
- }
- },
- {
- "name": "Edificio 27",
- "address": "Via Valvassori Peroni, Milano, 20133",
- "coords": {
- "latitude": 45.475868563542505,
- "longitude": 9.236353204609438
- }
- },
- {
- "name": "Edificio 22",
- "address": "Via Golgi 42, Milano, 20133",
- "coords": {
- "latitude": 45.47796163250129,
- "longitude": 9.234955773844867
- }
- },
- {
- "name": "Edificio 23",
- "address": "Via Golgi 40, Milano, 20133",
- "coords": {
- "latitude": 45.47770332464026,
- "longitude": 9.234945870954828
- }
- },
- {
- "name": "Edificio 24",
- "address": "Via Golgi 40, Milano, 20133",
- "coords": {
- "latitude": 45.47747417957433,
- "longitude": 9.23470424043846
- }
- },
- {
- "name": "Edificio 25",
- "address": "Via U.B. Secondo 3, Milano, 20133",
- "coords": {
- "latitude": 45.47750473230304,
- "longitude": 9.23513402586612
- }
- }
- ]
- },
- {
- "name": ["Mancinelli"],
- "buildings": [
- {
- "name": "Edificio 28",
- "address": "Via Mancinelli 7, Milano, 20133",
- "coords": {
- "latitude": 45.49016309824922,
- "longitude": 9.226888094653553
- }
- }
- ]
- },
- {
- "name": ["Pascoli"],
- "buildings": [
- {
- "name": "Edificio 38",
- "address": "Via Pascoli 70/3, Milano, 20133",
- "coords": {
- "latitude": 45.47547780481562,
- "longitude": 9.22570000206852
- }
- },
- {
- "name": "Edificio 39",
- "address": "Via Pascoli 70/3, Milano, 20133",
- "coords": {
- "latitude": 45.475677913901855,
- "longitude": 9.225758755850668
- }
- },
- {
- "name": "Edificio 40",
- "address": "Via Pascoli 70/3, Milano, 20133",
- "coords": {
- "latitude": 45.47591627820953,
- "longitude": 9.225771345946843
- }
- }
- ]
- },
- {
- "name": ["Romagna"],
- "buildings": [
- {
- "name": "Casa dello Studente",
- "address": "Viale Romagna 62, Milano, 20133",
- "coords": {
- "latitude": 45.47678010082273,
- "longitude": 9.224452739758812
- }
- }
- ]
+ {
+ "acronym": "MIA",
+ "campus": [
+ {
+ "name": [
+ "Leonardo"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 29",
+ "address": "Piazza Leonardo da Vinci 26, Milano, 20133",
+ "coords": {
+ "latitude": 45.47668740966992,
+ "longitude": 9.226326859295256
}
+ },
+ {
+ "name": "Edificio 1",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.47811790554435,
+ "longitude": 9.227725945733395
+ }
+ },
+ {
+ "name": "Edificio 10",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.47912809822935,
+ "longitude": 9.229883268245544
+ }
+ },
+ {
+ "name": "Edificio 2",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.4788249919485,
+ "longitude": 9.227210008150676
+ }
+ },
+ {
+ "name": "Edificio 2A",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.47876288697592,
+ "longitude": 9.227837695286086
+ }
+ },
+ {
+ "name": "Edificio 3",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.477435603580254,
+ "longitude": 9.227835389634977
+ }
+ },
+ {
+ "name": "Edificio 3A",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.47729656843257,
+ "longitude": 9.22805442460651
+ }
+ },
+ {
+ "name": "Edificio 4",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.478602838628646,
+ "longitude": 9.22845329881462
+ }
+ },
+ {
+ "name": "Edificio 4A",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.478974667422236,
+ "longitude": 9.228990510865588
+ }
+ },
+ {
+ "name": "Edificio 5",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.47769427270723,
+ "longitude": 9.228464826976882
+ }
+ },
+ {
+ "name": "Edificio 6",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.47825202398337,
+ "longitude": 9.22875994776181
+ }
+ },
+ {
+ "name": "Edificio 7",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.47814209083751,
+ "longitude": 9.229737535377756
+ }
+ },
+ {
+ "name": "Edificio 8",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.478809769736515,
+ "longitude": 9.229442414594473
+ }
+ },
+ {
+ "name": "Edificio 9",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.47759727192502,
+ "longitude": 9.229230296528302
+ }
+ },
+ {
+ "name": "Edificio 9A",
+ "address": "Piazza Leonardo da Vinci 32, Milano, 20133",
+ "coords": {
+ "latitude": 45.4771381326113,
+ "longitude": 9.229815926853346
+ }
+ }
+ ]
+ },
+ {
+ "name": [
+ "Bassini"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 19",
+ "address": "Via Ponzio 34/3, Milano, 20133",
+ "coords": {
+ "latitude": 45.47879081655148,
+ "longitude": 9.231155363015363
+ }
+ },
+ {
+ "name": "Edificio 20",
+ "address": "Via Ponzio 34/5, Milano, 20133",
+ "coords": {
+ "latitude": 45.478695312571354,
+ "longitude": 9.232531759044313
+ }
+ },
+ {
+ "name": "Edificio 21",
+ "address": "Via Golgi 39, Milano, 20133",
+ "coords": {
+ "latitude": 45.479048844048855,
+ "longitude": 9.233791065831895
+ }
+ },
+ {
+ "name": "Edificio 36",
+ "address": "Via Golgi 39, Milano, 20133",
+ "coords": {
+ "latitude": 45.47839707102326,
+ "longitude": 9.232902143392922
+ }
+ },
+ {
+ "name": "Edificio 36A",
+ "address": "Via Golgi 39, Milano, 20133",
+ "coords": {
+ "latitude": 45.47840377309843,
+ "longitude": 9.233573614377585
+ }
+ },
+ {
+ "name": "Edificio 37",
+ "address": "Via Golgi 39, Milano, 20133",
+ "coords": {
+ "latitude": 45.47840377309843,
+ "longitude": 9.233934440407387
+ }
+ },
+ {
+ "name": "Edificio 42",
+ "address": "Via Bassini 34/3, Milano, 20133",
+ "coords": {
+ "latitude": 45.47751909234621,
+ "longitude": 9.231437333034433
+ }
+ },
+ {
+ "name": "Edificio 43",
+ "address": "Via Bassini 34/3, Milano, 20133",
+ "coords": {
+ "latitude": 45.477644758070845,
+ "longitude": 9.231425385160406
+ }
+ },
+ {
+ "name": "Isola Ecologica",
+ "address": "Via Bassini 2, Milano, 20133",
+ "coords": {
+ "latitude": 45.478764590939626,
+ "longitude": 9.234032129716745
+ }
+ }
+ ]
+ },
+ {
+ "name": [
+ "Bonardi"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 11",
+ "address": "Via Ampère 2, Milano, 20133",
+ "coords": {
+ "latitude": 45.479700368402455,
+ "longitude": 9.227144319107985
+ }
+ },
+ {
+ "name": "Edificio 11B",
+ "address": "Via Ampère 4, Milano, 20133",
+ "coords": {
+ "latitude": 45.48039066193507,
+ "longitude": 9.226718974511959
+ }
+ },
+ {
+ "name": "Edificio 12",
+ "address": "Via Bonardi 3, Milano, 20133",
+ "coords": {
+ "latitude": 45.479559627904706,
+ "longitude": 9.227662857193996
+ }
+ },
+ {
+ "name": "Edificio 13",
+ "address": "Via Bonardi 9, Milano, 20133",
+ "coords": {
+ "latitude": 45.47986624067945,
+ "longitude": 9.228233965961486
+ }
+ },
+ {
+ "name": "Edificio 14",
+ "address": "Via Bonardi 9, Milano, 20133",
+ "coords": {
+ "latitude": 45.47964507754049,
+ "longitude": 9.22878834771603
+ }
+ },
+ {
+ "name": "Edificio 14A",
+ "address": "Via Bonardi 9, Milano, 20133",
+ "coords": {
+ "latitude": 45.48014771978483,
+ "longitude": 9.229170679933038
+ }
+ },
+ {
+ "name": "Edificio 14B",
+ "address": "Via Bonardi 9, Milano, 20133",
+ "coords": {
+ "latitude": 45.48014771978483,
+ "longitude": 9.228752504070686
+ }
+ },
+ {
+ "name": "Edificio 15",
+ "address": "Via Ponzio 31, Milano, 20133",
+ "coords": {
+ "latitude": 45.47966685878651,
+ "longitude": 9.229574518342371
+ }
+ },
+ {
+ "name": "Edificio 16A",
+ "address": "Via Bonardi 9, Milano, 20133",
+ "coords": {
+ "latitude": 45.479556276937224,
+ "longitude": 9.228453806990538
+ }
+ },
+ {
+ "name": "Edificio 16B",
+ "address": "Via Bonardi 9, Milano, 20133",
+ "coords": {
+ "latitude": 45.48007902560742,
+ "longitude": 9.227603117798322
+ }
+ },
+ {
+ "name": "Edificio 16C",
+ "address": "Via Bonardi 9, Milano, 20133",
+ "coords": {
+ "latitude": 45.479629998198945,
+ "longitude": 9.229118109245283
+ }
+ },
+ {
+ "name": "Edificio 18",
+ "address": "Via Ponzio 33, Milano, 20133",
+ "coords": {
+ "latitude": 45.48018625550555,
+ "longitude": 9.229739399120684
+ }
+ }
+ ]
+ },
+ {
+ "name": [
+ "Colombo"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 32.1",
+ "address": "Via Colombo 40, Milano, 20133",
+ "coords": {
+ "latitude": 45.47213230193092,
+ "longitude": 9.22686863256574
+ }
+ },
+ {
+ "name": "Edificio 32.2",
+ "address": "Via Colombo 40, Milano, 20133",
+ "coords": {
+ "latitude": 45.47207569302287,
+ "longitude": 9.227194415489148
+ }
+ },
+ {
+ "name": "Edificio 32.3",
+ "address": "Via Colombo 40, Milano, 20133",
+ "coords": {
+ "latitude": 45.47184925682209,
+ "longitude": 9.227171351211384
+ }
+ },
+ {
+ "name": "Edificio 32.4",
+ "address": "Via Colombo 40, Milano, 20133",
+ "coords": {
+ "latitude": 45.47190990946507,
+ "longitude": 9.226883047739344
+ }
+ },
+ {
+ "name": "Edificio 32.5",
+ "address": "Via Colombo 40, Milano, 20133",
+ "coords": {
+ "latitude": 45.47175625597605,
+ "longitude": 9.226926293260147
+ }
+ },
+ {
+ "name": "Edificio 30",
+ "address": "Via Colombo 81, Milano, 20133",
+ "coords": {
+ "latitude": 45.47586392362531,
+ "longitude": 9.226261178708338
+ }
+ }
+ ]
+ },
+ {
+ "name": [
+ "Golgi"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 26",
+ "address": "Via Golgi 20, Milano, 20133",
+ "coords": {
+ "latitude": 45.47569395835836,
+ "longitude": 9.235024035751083
+ }
+ },
+ {
+ "name": "Edificio 27",
+ "address": "Via Valvassori Peroni, Milano, 20133",
+ "coords": {
+ "latitude": 45.475868563542505,
+ "longitude": 9.236353204609438
+ }
+ },
+ {
+ "name": "Edificio 22",
+ "address": "Via Golgi 42, Milano, 20133",
+ "coords": {
+ "latitude": 45.47796163250129,
+ "longitude": 9.234955773844867
+ }
+ },
+ {
+ "name": "Edificio 23",
+ "address": "Via Golgi 40, Milano, 20133",
+ "coords": {
+ "latitude": 45.47770332464026,
+ "longitude": 9.234945870954828
+ }
+ },
+ {
+ "name": "Edificio 24",
+ "address": "Via Golgi 40, Milano, 20133",
+ "coords": {
+ "latitude": 45.47747417957433,
+ "longitude": 9.23470424043846
+ }
+ },
+ {
+ "name": "Edificio 25",
+ "address": "Via U.B. Secondo 3, Milano, 20133",
+ "coords": {
+ "latitude": 45.47750473230304,
+ "longitude": 9.23513402586612
+ }
+ }
+ ]
+ },
+ {
+ "name": [
+ "Mancinelli"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 28",
+ "address": "Via Mancinelli 7, Milano, 20133",
+ "coords": {
+ "latitude": 45.49016309824922,
+ "longitude": 9.226888094653553
+ }
+ }
+ ]
+ },
+ {
+ "name": [
+ "Pascoli"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 38",
+ "address": "Via Pascoli 70/3, Milano, 20133",
+ "coords": {
+ "latitude": 45.47547780481562,
+ "longitude": 9.22570000206852
+ }
+ },
+ {
+ "name": "Edificio 39",
+ "address": "Via Pascoli 70/3, Milano, 20133",
+ "coords": {
+ "latitude": 45.475677913901855,
+ "longitude": 9.225758755850668
+ }
+ },
+ {
+ "name": "Edificio 40",
+ "address": "Via Pascoli 70/3, Milano, 20133",
+ "coords": {
+ "latitude": 45.47591627820953,
+ "longitude": 9.225771345946843
+ }
+ }
+ ]
+ },
+ {
+ "name": [
+ "Romagna"
+ ],
+ "buildings": [
+ {
+ "name": "Casa dello Studente",
+ "address": "Viale Romagna 62, Milano, 20133",
+ "coords": {
+ "latitude": 45.47678010082273,
+ "longitude": 9.224452739758812
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "acronym": "MIB",
+ "campus": [
+ {
+ "name": [
+ "Bovisa",
+ "Durando"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio B1",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.50526063108648,
+ "longitude": 9.166960640981896
+ }
+ },
+ {
+ "name": "Edificio B2",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.505856940521184,
+ "longitude": 9.16684246746718
+ }
+ },
+ {
+ "name": "Edificio B3",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.506291745504754,
+ "longitude": 9.16657066831335
+ }
+ },
+ {
+ "name": "Edificio B4",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.50582827267731,
+ "longitude": 9.1657801030213
+ }
+ },
+ {
+ "name": "Edificio B5",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.504051263792235,
+ "longitude": 9.165419660659406
+ }
+ },
+ {
+ "name": "Edificio B5A",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.50424070168094,
+ "longitude": 9.165416008016528
+ }
+ },
+ {
+ "name": "Edificio B6",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.50481669134817,
+ "longitude": 9.16627437531528
+ }
+ },
+ {
+ "name": "Edificio B7",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.504682097750845,
+ "longitude": 9.164140249884532
+ }
+ },
+ {
+ "name": "Edificio B8",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.50468698803176,
+ "longitude": 9.164754281608419
+ }
+ },
+ {
+ "name": "Edificio B9",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.50521269076449,
+ "longitude": 9.164468198661584
+ }
+ },
+ {
+ "name": "Edificio B9A",
+ "address": "Via Candiani 72, Milano, 20158",
+ "coords": {
+ "latitude": 45.50541074493551,
+ "longitude": 9.164988032336918
+ }
+ },
+ {
+ "name": "Infopoint",
+ "address": "Via Verità 25, Milano, 20158",
+ "coords": {
+ "latitude": 45.50448148112203,
+ "longitude": 9.165766681881529
+ }
+ }
+ ]
+ },
+ {
+ "name": [
+ "Bovisa",
+ "La Masa"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio B11",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.500846286602666,
+ "longitude": 9.155348601436222
+ }
+ },
+ {
+ "name": "Edificio B12",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50148227512907,
+ "longitude": 9.154387194659964
+ }
+ },
+ {
+ "name": "Edificio B13",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50157313004546,
+ "longitude": 9.155059639273848
+ }
+ },
+ {
+ "name": "Edificio B14",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.501563666,
+ "longitude": 9.156285702980878
+ }
+ },
+ {
+ "name": "Edificio B14A",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50161287903062,
+ "longitude": 9.156733999417478
+ }
+ },
+ {
+ "name": "Edificio B15",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50188922830498,
+ "longitude": 9.156825819163954
+ }
+ },
+ {
+ "name": "Edificio B16",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.501845693924324,
+ "longitude": 9.15774941782049
+ }
+ },
+ {
+ "name": "Edificio B16A",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50196304740825,
+ "longitude": 9.158189612507442
+ }
+ },
+ {
+ "name": "Edificio B18A",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50203686641096,
+ "longitude": 9.156566563416906
+ }
+ },
+ {
+ "name": "Edificio B18B",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50223182381833,
+ "longitude": 9.15721470280378
+ }
+ },
+ {
+ "name": "Edificio B18C",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50228860740229,
+ "longitude": 9.157603586435906
+ }
+ },
+ {
+ "name": "Edificio B19",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.502271572336156,
+ "longitude": 9.155699676957584
+ }
+ },
+ {
+ "name": "Edificio B20",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50239838883989,
+ "longitude": 9.15493811315239
+ }
+ },
+ {
+ "name": "Edificio B21",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50104305808609,
+ "longitude": 9.15633786717546
+ }
+ },
+ {
+ "name": "Edificio B22",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50135848414706,
+ "longitude": 9.157643792042283
+ }
+ },
+ {
+ "name": "Edificio B23",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50095617559604,
+ "longitude": 9.15800589026771
+ }
+ },
+ {
+ "name": "Edificio B24",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50170591921368,
+ "longitude": 9.153366080649027
+ }
+ },
+ {
+ "name": "Edificio B29",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.50128945237324,
+ "longitude": 9.15353385381083
+ }
+ },
+ {
+ "name": "Edificio B30",
+ "address": "Via La Masa 34, Milano, 20156",
+ "coords": {
+ "latitude": 45.501549132062195,
+ "longitude": 9.155347901172796
+ }
+ },
+ {
+ "name": "Edificio B37",
+ "address": "Via Lambruschini 4, Milano, 20156",
+ "coords": {
+ "latitude": 45.5029063064303,
+ "longitude": 9.156305606322812
+ }
+ },
+ {
+ "name": "Edificio BL25",
+ "address": "Via Lambruschini 4, Milano, 20156",
+ "coords": {
+ "latitude": 45.50309248664372,
+ "longitude": 9.155917630899358
+ }
+ },
+ {
+ "name": "Edificio BL25A",
+ "address": "Via Lambruschini 4, Milano, 20156",
+ "coords": {
+ "latitude": 45.50284016331667,
+ "longitude": 9.15555412238212
+ }
+ },
+ {
+ "name": "Edificio BL26",
+ "address": "Via Lambruschini 4, Milano, 20156",
+ "coords": {
+ "latitude": 45.50339625303833,
+ "longitude": 9.156018993853149
+ }
+ },
+ {
+ "name": "Edificio BL27",
+ "address": "Via Lambruschini 4, Milano, 20156",
+ "coords": {
+ "latitude": 45.50366327214294,
+ "longitude": 9.157438075212218
+ }
+ },
+ {
+ "name": "Edificio BL28",
+ "address": "Via Lambruschini 4, Milano, 20156",
+ "coords": {
+ "latitude": 45.503143931072984,
+ "longitude": 9.157036118688078
+ }
+ }
]
- },
- {
- "acronym": "MIB",
- "campus": [
- {
- "name": ["Bovisa", "Durando"],
- "buildings": [
- {
- "name": "Edificio B1",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.50526063108648,
- "longitude": 9.166960640981896
- }
- },
- {
- "name": "Edificio B2",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.505856940521184,
- "longitude": 9.16684246746718
- }
- },
- {
- "name": "Edificio B3",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.506291745504754,
- "longitude": 9.16657066831335
- }
- },
- {
- "name": "Edificio B4",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.50582827267731,
- "longitude": 9.1657801030213
- }
- },
- {
- "name": "Edificio B5",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.504051263792235,
- "longitude": 9.165419660659406
- }
- },
- {
- "name": "Edificio B5A",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.50424070168094,
- "longitude": 9.165416008016528
- }
- },
- {
- "name": "Edificio B6",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.50481669134817,
- "longitude": 9.16627437531528
- }
- },
- {
- "name": "Edificio B7",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.504682097750845,
- "longitude": 9.164140249884532
- }
- },
- {
- "name": "Edificio B8",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.50468698803176,
- "longitude": 9.164754281608419
- }
- },
- {
- "name": "Edificio B9",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.50521269076449,
- "longitude": 9.164468198661584
- }
- },
- {
- "name": "Edificio B9A",
- "address": "Via Candiani 72, Milano, 20158",
- "coords": {
- "latitude": 45.50541074493551,
- "longitude": 9.164988032336918
- }
- },
- {
- "name": "Infopoint",
- "address": "Via Verità 25, Milano, 20158",
- "coords": {
- "latitude": 45.50448148112203,
- "longitude": 9.165766681881529
- }
- }
- ]
- },
- {
- "name": ["Bovisa", "La Masa"],
- "buildings": [
- {
- "name": "Edificio B11",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.500846286602666,
- "longitude": 9.155348601436222
- }
- },
- {
- "name": "Edificio B12",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50148227512907,
- "longitude": 9.154387194659964
- }
- },
- {
- "name": "Edificio B13",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50157313004546,
- "longitude": 9.155059639273848
- }
- },
- {
- "name": "Edificio B14",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.501563666,
- "longitude": 9.156285702980878
- }
- },
- {
- "name": "Edificio B14A",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50161287903062,
- "longitude": 9.156733999417478
- }
- },
- {
- "name": "Edificio B15",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50188922830498,
- "longitude": 9.156825819163954
- }
- },
- {
- "name": "Edificio B16",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.501845693924324,
- "longitude": 9.15774941782049
- }
- },
- {
- "name": "Edificio B16A",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50196304740825,
- "longitude": 9.158189612507442
- }
- },
- {
- "name": "Edificio B18A",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50203686641096,
- "longitude": 9.156566563416906
- }
- },
- {
- "name": "Edificio B18B",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50223182381833,
- "longitude": 9.15721470280378
- }
- },
- {
- "name": "Edificio B18C",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50228860740229,
- "longitude": 9.157603586435906
- }
- },
- {
- "name": "Edificio B19",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.502271572336156,
- "longitude": 9.155699676957584
- }
- },
- {
- "name": "Edificio B20",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50239838883989,
- "longitude": 9.15493811315239
- }
- },
- {
- "name": "Edificio B21",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50104305808609,
- "longitude": 9.15633786717546
- }
- },
- {
- "name": "Edificio B22",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50135848414706,
- "longitude": 9.157643792042283
- }
- },
- {
- "name": "Edificio B23",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50095617559604,
- "longitude": 9.15800589026771
- }
- },
- {
- "name": "Edificio B24",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50170591921368,
- "longitude": 9.153366080649027
- }
- },
- {
- "name": "Edificio B29",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.50128945237324,
- "longitude": 9.15353385381083
- }
- },
- {
- "name": "Edificio B30",
- "address": "Via La Masa 34, Milano, 20156",
- "coords": {
- "latitude": 45.501549132062195,
- "longitude": 9.155347901172796
- }
- },
- {
- "name": "Edificio B37",
- "address": "Via Lambruschini 4, Milano, 20156",
- "coords": {
- "latitude": 45.5029063064303,
- "longitude": 9.156305606322812
- }
- },
- {
- "name": "Edificio BL25",
- "address": "Via Lambruschini 4, Milano, 20156",
- "coords": {
- "latitude": 45.50309248664372,
- "longitude": 9.155917630899358
- }
- },
- {
- "name": "Edificio BL25A",
- "address": "Via Lambruschini 4, Milano, 20156",
- "coords": {
- "latitude": 45.50284016331667,
- "longitude": 9.15555412238212
- }
- },
- {
- "name": "Edificio BL26",
- "address": "Via Lambruschini 4, Milano, 20156",
- "coords": {
- "latitude": 45.50339625303833,
- "longitude": 9.156018993853149
- }
- },
- {
- "name": "Edificio BL27",
- "address": "Via Lambruschini 4, Milano, 20156",
- "coords": {
- "latitude": 45.50366327214294,
- "longitude": 9.157438075212218
- }
- },
- {
- "name": "Edificio BL28",
- "address": "Via Lambruschini 4, Milano, 20156",
- "coords": {
- "latitude": 45.503143931072984,
- "longitude": 9.157036118688078
- }
- }
- ]
+ }
+ ]
+ },
+ {
+ "acronym": "CRG",
+ "campus": [
+ {
+ "name": [
+ "Sesto"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio C",
+ "address": "Via Sesto 39, Cremona, 26100",
+ "coords": {
+ "latitude": 45.147121757649806,
+ "longitude": 10.00162101166769
+ }
+ },
+ {
+ "name": "Palazzina A",
+ "address": "Via Sesto 39, Cremona, 26100",
+ "coords": {
+ "latitude": 45.14624583991279,
+ "longitude": 10.002210009658127
+ }
+ },
+ {
+ "name": "Palazzina B",
+ "address": "Via Sesto 39, Cremona, 26100",
+ "coords": {
+ "latitude": 45.146619394711394,
+ "longitude": 10.001899530097274
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "acronym": "LCF",
+ "campus": [
+ {
+ "name": [
+ "Ghislanzoni"
+ ],
+ "buildings": [
+ {
+ "name": "Residenza Loos",
+ "address": "Via Ghislanzoni 24, Lecco, 23900",
+ "coords": {
+ "latitude": 45.84944207561925,
+ "longitude": 9.397439941157165
+ }
+ },
+ {
+ "name": "BEEpilot",
+ "address": "Via Previati 1C, Lecco, 23900",
+ "coords": {
+ "latitude": 45.84889332151791,
+ "longitude": 9.39735373582034
+ }
+ },
+ {
+ "name": "Edificio 10",
+ "address": "Via Previati 1C, Lecco, 23900",
+ "coords": {
+ "latitude": 45.84945959386757,
+ "longitude": 9.396282096446393
+ }
+ },
+ {
+ "name": "Edificio 11",
+ "address": "Via Previati 1C, Lecco, 23900",
+ "coords": {
+ "latitude": 45.84976868042763,
+ "longitude": 9.397024120135281
+ }
+ },
+ {
+ "name": "Edificio 12",
+ "address": "Via Previati 1C, Lecco, 23900",
+ "coords": {
+ "latitude": 45.850239482856416,
+ "longitude": 9.396348203485335
+ }
+ },
+ {
+ "name": "Edificio 5",
+ "address": "Via Previati 1C, Lecco, 23900",
+ "coords": {
+ "latitude": 45.84992561501641,
+ "longitude": 9.396852458762153
+ }
+ },
+ {
+ "name": "Edificio 8",
+ "address": "Via Previati 1C, Lecco, 23900",
+ "coords": {
+ "latitude": 45.84920819614676,
+ "longitude": 9.39701875573217
+ }
+ },
+ {
+ "name": "Edificio 9",
+ "address": "Via Previati 1C, Lecco, 23900",
+ "coords": {
+ "latitude": 45.84890553228907,
+ "longitude": 9.396487678342055
+ }
+ },
+ {
+ "name": "Edificio CNR",
+ "address": "Via Previati 1C, Lecco, 23900",
+ "coords": {
+ "latitude": 45.84854681743879,
+ "longitude": 9.397254790092957
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "acronym": "PCL",
+ "campus": [
+ {
+ "name": [
+ "Scalabrini"
+ ],
+ "buildings": [
+ {
+ "name": "Padiglione 11",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04671253164241,
+ "longitude": 9.703538101434237
+ }
+ },
+ {
+ "name": "Padiglione 12",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04746700688415,
+ "longitude": 9.703336354556205
+ }
+ },
+ {
+ "name": "Padiglione 13",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04736378936126,
+ "longitude": 9.703562450197184
+ }
+ },
+ {
+ "name": "Padiglione 14",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04705133747066,
+ "longitude": 9.702656152043621
+ }
+ },
+ {
+ "name": "Padiglione 15",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04645536532436,
+ "longitude": 9.703416037344196
+ }
+ },
+ {
+ "name": "Padiglione 2",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04688035667178,
+ "longitude": 9.703307226084346
+ }
+ },
+ {
+ "name": "Padiglione 3",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04654833371806,
+ "longitude": 9.70320343683441
+ }
+ },
+ {
+ "name": "Padiglione 4",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04667055098037,
+ "longitude": 9.702900718188767
+ }
+ },
+ {
+ "name": "Padiglione 5",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.046444448839786,
+ "longitude": 9.702814227147154
+ }
+ },
+ {
+ "name": "Padiglione 6",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04676832460221,
+ "longitude": 9.702612414716725
+ }
+ },
+ {
+ "name": "Padiglione 8",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.0465911097912,
+ "longitude": 9.702324111225455
+ }
+ },
+ {
+ "name": "Padiglione 9",
+ "address": "Via Scalabrini 113, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.046383339999025,
+ "longitude": 9.702499976344225
+ }
+ },
+ {
+ "name": "Edificio 1",
+ "address": "Via Scalabrini 76, Piacenza, 29100",
+ "coords": {
+ "latitude": 45.04830239234551,
+ "longitude": 9.701883338558217
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "acronym": "MNI",
+ "campus": [
+ {
+ "name": [
+ "Scarsellini"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 1",
+ "address": "Via Scarsellini 15, Mantova, 46100",
+ "coords": {
+ "latitude": 45.160352957787765,
+ "longitude": 10.788892210362015
+ }
+ },
+ {
+ "name": "Edificio B",
+ "address": "Via Scarsellini 2, Mantova, 46100",
+ "coords": {
+ "latitude": 45.16071402717656,
+ "longitude": 10.78813888256507
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "acronym": "MIC",
+ "campus": [
+ {
+ "name": [
+ "Off",
+ "Campus"
+ ],
+ "buildings": [
+ {
+ "name": "NOLO",
+ "address": "Viale Monza 54, Milano, 20128",
+ "coords": {
+ "latitude": 45.49326461001558,
+ "longitude": 9.21927698715338
+ }
+ },
+ {
+ "name": "San Siro",
+ "address": "Viale Gigante, Milano, 20148",
+ "coords": {
+ "latitude": 45.471604941331265,
+ "longitude": 9.138379698192313
}
+ }
]
- },
- {
- "acronym": "CRG",
- "campus": [
- {
- "name": ["Sesto"],
- "buildings": [
- {
- "name": "Edificio C",
- "address": "Via Sesto 39, Cremona, 26100",
- "coords": {
- "latitude": 45.147121757649806,
- "longitude": 10.00162101166769
- }
- },
- {
- "name": "Palazzina A",
- "address": "Via Sesto 39, Cremona, 26100",
- "coords": {
- "latitude": 45.14624583991279,
- "longitude": 10.002210009658127
- }
- },
- {
- "name": "Palazzina B",
- "address": "Via Sesto 39, Cremona, 26100",
- "coords": {
- "latitude": 45.146619394711394,
- "longitude": 10.001899530097274
- }
- }
- ]
+ },
+ {
+ "name": [
+ "Residenza",
+ "Einstein"
+ ],
+ "buildings": [
+ {
+ "name": "Einstein",
+ "address": "Via Einstein 6, Milano, 20137",
+ "coords": {
+ "latitude": 45.45033404949838,
+ "longitude": 9.216969652664448
}
+ }
]
- },
- {
- "acronym": "LCF",
- "campus": [
- {
- "name": ["Ghislanzoni"],
- "buildings": [
- {
- "name": "Residenza Loos",
- "address": "Via Ghislanzoni 24, Lecco, 23900",
- "coords": {
- "latitude": 45.84944207561925,
- "longitude": 9.397439941157165
- }
- },
- {
- "name": "BEEpilot",
- "address": "Via Previati 1C, Lecco, 23900",
- "coords": {
- "latitude": 45.84889332151791,
- "longitude": 9.39735373582034
- }
- },
- {
- "name": "Edificio 10",
- "address": "Via Previati 1C, Lecco, 23900",
- "coords": {
- "latitude": 45.84945959386757,
- "longitude": 9.396282096446393
- }
- },
- {
- "name": "Edificio 11",
- "address": "Via Previati 1C, Lecco, 23900",
- "coords": {
- "latitude": 45.84976868042763,
- "longitude": 9.397024120135281
- }
- },
- {
- "name": "Edificio 12",
- "address": "Via Previati 1C, Lecco, 23900",
- "coords": {
- "latitude": 45.850239482856416,
- "longitude": 9.396348203485335
- }
- },
- {
- "name": "Edificio 5",
- "address": "Via Previati 1C, Lecco, 23900",
- "coords": {
- "latitude": 45.84992561501641,
- "longitude": 9.396852458762153
- }
- },
- {
- "name": "Edificio 8",
- "address": "Via Previati 1C, Lecco, 23900",
- "coords": {
- "latitude": 45.84920819614676,
- "longitude": 9.39701875573217
- }
- },
- {
- "name": "Edificio 9",
- "address": "Via Previati 1C, Lecco, 23900",
- "coords": {
- "latitude": 45.84890553228907,
- "longitude": 9.396487678342055
- }
- },
- {
- "name": "Edificio CNR",
- "address": "Via Previati 1C, Lecco, 23900",
- "coords": {
- "latitude": 45.84854681743879,
- "longitude": 9.397254790092957
- }
- }
- ]
+ },
+ {
+ "name": [
+ "Residenza",
+ "Newton"
+ ],
+ "buildings": [
+ {
+ "name": "Newton",
+ "address": "Via Mario Borsa 25, Milano, 20151",
+ "coords": {
+ "latitude": 45.50201311059991,
+ "longitude": 9.100693099933826
}
+ }
]
- },
- {
- "acronym": "PCL",
- "campus": [
- {
- "name": ["Scalabrini"],
- "buildings": [
- {
- "name": "Padiglione 11",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04671253164241,
- "longitude": 9.703538101434237
- }
- },
- {
- "name": "Padiglione 12",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04746700688415,
- "longitude": 9.703336354556205
- }
- },
- {
- "name": "Padiglione 13",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04736378936126,
- "longitude": 9.703562450197184
- }
- },
- {
- "name": "Padiglione 14",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04705133747066,
- "longitude": 9.702656152043621
- }
- },
- {
- "name": "Padiglione 15",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04645536532436,
- "longitude": 9.703416037344196
- }
- },
- {
- "name": "Padiglione 2",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04688035667178,
- "longitude": 9.703307226084346
- }
- },
- {
- "name": "Padiglione 3",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04654833371806,
- "longitude": 9.70320343683441
- }
- },
- {
- "name": "Padiglione 4",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04667055098037,
- "longitude": 9.702900718188767
- }
- },
- {
- "name": "Padiglione 5",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.046444448839786,
- "longitude": 9.702814227147154
- }
- },
- {
- "name": "Padiglione 6",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.04676832460221,
- "longitude": 9.702612414716725
- }
- },
- {
- "name": "Padiglione 8",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.0465911097912,
- "longitude": 9.702324111225455
- }
- },
- {
- "name": "Padiglione 9",
- "address": "Via Scalabrini 113, Piacenza, 29100",
- "coords": {
- "latitude": 45.046383339999025,
- "longitude": 9.702499976344225
- }
- },
- {
- "name": "Edificio 1",
- "address": "Via Scalabrini 76, Piacenza, 29100",
- "coords": {
- "latitude": 45.04830239234551,
- "longitude": 9.701883338558217
- }
- }
- ]
+ },
+ {
+ "name": [
+ "Residenza",
+ "Pareto"
+ ],
+ "buildings": [
+ {
+ "name": "Pareto",
+ "address": "Via Maggianico 6, Milano, 20156",
+ "coords": {
+ "latitude": 45.50331624885291,
+ "longitude": 9.145443677552473
}
+ }
]
- },
- {
- "acronym": "MNI",
- "campus": [
- {
- "name": ["Scarsellini"],
- "buildings": [
- {
- "name": "Edificio 1",
- "address": "Via Scarsellini 15, Mantova, 46100",
- "coords": {
- "latitude": 45.160352957787765,
- "longitude": 10.788892210362015
- }
- },
- {
- "name": "Edificio B",
- "address": "Via Scarsellini 2, Mantova, 46100",
- "coords": {
- "latitude": 45.16071402717656,
- "longitude": 10.78813888256507
- }
- }
- ]
+ }
+ ]
+ },
+ {
+ "acronym": "MID",
+ "campus": [
+ {
+ "name": [
+ "Calabria"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 1",
+ "address": "Via Calabria 4, Milano, 20098",
+ "coords": {
+ "latitude": 45.39350641657452,
+ "longitude": 9.257432613353823
}
+ }
]
- },
- {
- "acronym": "MIC",
- "campus": [
- {
- "name": ["Off", "Campus"],
- "buildings": [
- {
- "name": "NOLO",
- "address": "Viale Monza 54, Milano, 20128",
- "coords": {
- "latitude": 45.49326461001558,
- "longitude": 9.21927698715338
- }
- },
- {
- "name": "San Siro",
- "address": "Viale Gigante, Milano, 20148",
- "coords": {
- "latitude": 45.471604941331265,
- "longitude": 9.138379698192313
- }
- }
- ]
- },
- {
- "name": ["Residenza", "Einstein"],
- "buildings": [
- {
- "name": "Einstein",
- "address": "Via Einstein 6, Milano, 20137",
- "coords": {
- "latitude": 45.45033404949838,
- "longitude": 9.216969652664448
- }
- }
- ]
- },
- {
- "name": ["Residenza", "Newton"],
- "buildings": [
- {
- "name": "Newton",
- "address": "Via Mario Borsa 25, Milano, 20151",
- "coords": {
- "latitude": 45.50201311059991,
- "longitude": 9.100693099933826
- }
- }
- ]
- },
- {
- "name": ["Residenza", "Pareto"],
- "buildings": [
- {
- "name": "Pareto",
- "address": "Via Maggianico 6, Milano, 20156",
- "coords": {
- "latitude": 45.50331624885291,
- "longitude": 9.145443677552473
- }
- }
- ]
+ }
+ ]
+ },
+ {
+ "acronym": "COE",
+ "campus": [
+ {
+ "name": [
+ "Anzani"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 4",
+ "address": "Via Anzani 42, Como, 22100",
+ "coords": {
+ "latitude": 45.80120256319488,
+ "longitude": 9.092668671639375
}
+ }
]
- },
- {
- "acronym": "MID",
- "campus": [
- {
- "name": ["Calabria"],
- "buildings": [
- {
- "name": "Edificio 1",
- "address": "Via Calabria 4, Milano, 20098",
- "coords": {
- "latitude": 45.39350641657452,
- "longitude": 9.257432613353823
- }
- }
- ]
+ },
+ {
+ "name": [
+ "Castelnuovo"
+ ],
+ "buildings": [
+ {
+ "name": "Edificio 1",
+ "address": "Via Castelnuovo 7, Como, 22100",
+ "coords": {
+ "latitude": 45.80276883790487,
+ "longitude": 9.09505146871641
}
+ }
]
- },
- {
- "acronym": "COE",
- "campus": [
- {
- "name": ["Anzani"],
- "buildings": [
- {
- "name": "Edificio 4",
- "address": "Via Anzani 42, Como, 22100",
- "coords": {
- "latitude": 45.80120256319488,
- "longitude": 9.092668671639375
- }
- }
- ]
- },
- {
- "name": ["Castelnuovo"],
- "buildings": [
- {
- "name": "Edificio 1",
- "address": "Via Castelnuovo 7, Como, 22100",
- "coords": {
- "latitude": 45.80276883790487,
- "longitude": 9.09505146871641
- }
- }
- ]
- },
- {
- "name": ["Zezio"],
- "buildings": [
- {
- "name": "Residenza La Presentazione",
- "address": "Via Zezio 58, Como, 22100",
- "coords": {
- "latitude": 45.80645610020381,
- "longitude": 9.09718826871654
- }
- }
- ]
+ },
+ {
+ "name": [
+ "Zezio"
+ ],
+ "buildings": [
+ {
+ "name": "Residenza La Presentazione",
+ "address": "Via Zezio 58, Como, 22100",
+ "coords": {
+ "latitude": 45.80645610020381,
+ "longitude": 9.09718826871654
}
+ }
]
- }
-]
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/src/components/Home/MainMenu.tsx b/src/components/Home/MainMenu.tsx
index e9520a36..e2eeee65 100644
--- a/src/components/Home/MainMenu.tsx
+++ b/src/components/Home/MainMenu.tsx
@@ -16,7 +16,6 @@ import grading_book from "assets/menu/grading_book.svg"
import tests from "assets/menu/tests.svg"
import add from "assets/menu/add.svg"
import { ModalCustom } from "components/Modal"
-
import AsyncStorage from "@react-native-async-storage/async-storage"
import { useOutsideClick } from "utils/outsideClick"
@@ -199,7 +198,7 @@ export const MainMenu: FC<{ filter?: string }> = ({ filter }) => {
onPress={() => {
if (isDeleting) setIsDeleting(false)
else {
- buttonIcon.onClick()
+ buttonIcon.onClick?.()
}
}}
onLongPress={() => {
diff --git a/src/navigation/MainStackNavigator.tsx b/src/navigation/MainStackNavigator.tsx
index 8858db9b..90a0fa67 100644
--- a/src/navigation/MainStackNavigator.tsx
+++ b/src/navigation/MainStackNavigator.tsx
@@ -15,6 +15,7 @@ import { CampusChoice } from "pages/FreeClass/CampusChoice"
import { PositionChoice } from "pages/FreeClass/PositionChoice"
import { BuildingChoice } from "pages/FreeClass/BuildingChoice"
import { ClassChoice } from "pages/FreeClass/ClassChoice"
+import { RoomDetails } from "pages/FreeClass/RoomDetails"
import { OtherCategories } from "pages/news/OtherCategories"
import { Groups } from "pages/Groups"
@@ -46,6 +47,7 @@ export const MainStack: FC = () => {
component={BuildingChoice}
/>
+
diff --git a/src/navigation/NavigationTypes.ts b/src/navigation/NavigationTypes.ts
index 00a94b8b..2da8db13 100644
--- a/src/navigation/NavigationTypes.ts
+++ b/src/navigation/NavigationTypes.ts
@@ -25,6 +25,7 @@ import { Article } from "api/articles"
import { CampusItem } from "pages/FreeClass/CampusChoice"
import { NavigatorScreenParams } from "@react-navigation/native"
import { BuildingItem } from "pages/FreeClass/BuildingChoice"
+import { Occupancies, RoomDetails } from "api/rooms"
import { TagWithData } from "contexts/newsPreferences"
/**
@@ -52,6 +53,15 @@ export type MainStackNavigatorParams = {
CampusChoice: { currentDate: string }
PositionChoice: undefined
BuildingChoice: { campus: CampusItem; currentDate: string }
+ RoomDetails: {
+ room: RoomDetails
+ startDate: string
+ roomId: number
+ roomLatitude?: number
+ roomLongitude?: number
+ occupancies?: Occupancies
+ occupancyRate?: number | null
+ }
ClassChoice: { building: BuildingItem; currentDate: string }
Groups: undefined
}
diff --git a/src/pages/FreeClass/BuildingChoice.tsx b/src/pages/FreeClass/BuildingChoice.tsx
index 4223ea06..e318b529 100644
--- a/src/pages/FreeClass/BuildingChoice.tsx
+++ b/src/pages/FreeClass/BuildingChoice.tsx
@@ -70,7 +70,8 @@ export const BuildingChoice: MainStackScreen<"BuildingChoice"> = props => {
{
roomId: room.room_id,
name: room.name,
- occupancyRate: room.occupancyRate,
+ occupancies: room.occupancies,
+ occupancyRate: room.occupancy_rate ?? undefined,
},
],
}
@@ -84,7 +85,8 @@ export const BuildingChoice: MainStackScreen<"BuildingChoice"> = props => {
tempBuildings[indexElement].freeRoomList.push({
roomId: room.room_id,
name: room.name,
- occupancyRate: room.occupancyRate,
+ occupancies: room.occupancies,
+ occupancyRate: room.occupancy_rate ?? undefined,
})
}
})
@@ -103,8 +105,15 @@ export const BuildingChoice: MainStackScreen<"BuildingChoice"> = props => {
setDate(new Date(currentDate))
}, [props.route.params.currentDate])
+ //custom goBack function, in order to maintain the currentDate.
+ const goBack = () => {
+ props.navigation.navigate("CampusChoice", {
+ currentDate: date.toString(),
+ })
+ }
+
return (
-
+ goBack() }}>
{campus.name.length > 1 ? (
= props => {
setDate(new Date(currentDate))
}, [props.route.params.currentDate])
+ //custom goBack function in order to maintain the currenyDate
+ const goBack = () => {
+ props.navigation.navigate("BuildingChoice", {
+ campus: building.campus,
+ currentDate: date.toString(),
+ })
+ }
+
const buildingName: string[] = building.name.split(" ") // ex. buildingName = ["Ed.","B2"]
+ const coords = getBuildingCoords(
+ building.campus,
+ building.name.replace("Ed. ", "Edificio ")
+ )
+
return (
-
+ goBack() }}>
= props => {
setDate(date)} />
-
+
)
diff --git a/src/pages/FreeClass/PositionChoice.tsx b/src/pages/FreeClass/PositionChoice.tsx
index 49ff91d3..11b5aa29 100644
--- a/src/pages/FreeClass/PositionChoice.tsx
+++ b/src/pages/FreeClass/PositionChoice.tsx
@@ -2,7 +2,6 @@ import React, { useState, useEffect } from "react"
import { MainStackScreen } from "navigation/NavigationTypes"
import { Platform, View } from "react-native"
import { Title } from "components/Text"
-import { PoliSearchBar } from "components/Home"
import * as Location from "expo-location"
import { LocationGeocodedAddress, PermissionStatus } from "expo-location"
import { AddressText } from "components/FreeClass/AddressText"
@@ -115,7 +114,8 @@ export const PositionChoice: MainStackScreen<"PositionChoice"> = () => {
{
roomId: room.room_id,
name: room.name,
- occupancyRate: room.occupancyRate,
+ occupancies: room.occupancies,
+ occupancyRate: room.occupancy_rate ?? undefined,
},
],
}
@@ -129,14 +129,16 @@ export const PositionChoice: MainStackScreen<"PositionChoice"> = () => {
tempBuildings[indexElement].freeRoomList.push({
roomId: room.room_id,
name: room.name,
- occupancyRate: room.occupancyRate,
+ occupancies: room.occupancies,
+ occupancyRate: room.occupancy_rate ?? undefined,
})
}
if (tempRoomList.length < 50) {
tempRoomList.push({
roomId: room.room_id,
name: room.name,
- occupancyRate: room.occupancyRate,
+ occupancies: room.occupancies,
+ occupancyRate: room.occupancy_rate ?? undefined,
})
} else {
setRoomList(tempRoomList)
diff --git a/src/pages/FreeClass/RoomDetails.tsx b/src/pages/FreeClass/RoomDetails.tsx
new file mode 100644
index 00000000..d680636a
--- /dev/null
+++ b/src/pages/FreeClass/RoomDetails.tsx
@@ -0,0 +1,31 @@
+import { MainStackScreen } from "navigation/NavigationTypes"
+import React from "react"
+import { InfoMapTile } from "components/FreeClass/ClassDetails/InfoMapTile"
+import { TimeLeftTile } from "components/FreeClass/ClassDetails/TimeLeftTile"
+import { RoomUtilsSection } from "components/FreeClass/ClassDetails/RoomUtilsSection"
+import { CrowdingSection } from "components/FreeClass/ClassDetails/CrowdingSection"
+import { ContentWrapperScroll } from "components/ContentWrapperScroll"
+
+export const RoomDetails: MainStackScreen<"RoomDetails"> = props => {
+ const { room, startDate, roomId, roomLatitude, roomLongitude, occupancies } =
+ props.route.params
+
+ return (
+
+
+
+
+
+
+ )
+}
diff --git a/src/utils/colors.ts b/src/utils/colors.ts
index 279e0da1..14ce3745 100644
--- a/src/utils/colors.ts
+++ b/src/utils/colors.ts
@@ -9,6 +9,7 @@ const palette = {
lessDark: "#2B344A",
variant1: "#414867",
variant2: "#010B40",
+ variant3: "#454773",
accent: "#FFB544",
} as const
@@ -96,6 +97,21 @@ export interface ColorTheme {
* Dark blue used for the title in cards with a background image and a yellowish gradient.
*/
cardTitle: string
+
+ /**
+ * for RoomDetails page's slider
+ */
+ sliderBorderColor: string
+
+ /**
+ * dark blue in light mode, white in dark mode, used in slider labels
+ */
+ labelsHighContrast: string
+
+ /**
+ * purple/blueish in light mode, white in dark mode, used in TimeLeftTile
+ */
+ iconHighContrast: string
}
/**
@@ -181,6 +197,9 @@ export const usePalette: () => ColorTheme &
articleTitle: palette.darker,
articleSubtitle: palette.primary,
cardTitle: palette.variant2, // "#010B40"
+ sliderBorderColor: "#454773",
+ labelsHighContrast: palette.variant1, // "#414867",
+ iconHighContrast: palette.variant3, // "#454773",
}
const darkTheme: ColorTheme = {
@@ -197,6 +216,9 @@ export const usePalette: () => ColorTheme &
articleTitle: "#FFFFFF",
articleSubtitle: palette.lighter,
cardTitle: palette.variant2, // "#010B40"
+ sliderBorderColor: "#FFFFFF",
+ labelsHighContrast: "#FFFFFF",
+ iconHighContrast: "#FFFFFF",
}
const colors = isLight ? lightTheme : darkTheme
diff --git a/src/utils/rooms.ts b/src/utils/rooms.ts
new file mode 100644
index 00000000..42ef3d82
--- /dev/null
+++ b/src/utils/rooms.ts
@@ -0,0 +1,135 @@
+import BuildingListJSON from "components/FreeClass/buildingCoords.json"
+import { CampusItem } from "pages/FreeClass/CampusChoice"
+import { Occupancies } from "api/rooms"
+
+export function extractRoom(val: string) {
+ const arr = val.split(".")
+ if (arr.length > 2) {
+ return arr.slice(1).join(".")
+ } else {
+ return val
+ }
+}
+
+export function extractBuilding(val: string) {
+ const arr = val.split(" ")
+ if (arr.length === 2) {
+ return arr[1]
+ }
+ return undefined
+}
+
+/* function containsNumber(val: string) {
+ // if has digits
+ const regExp = /\d/g
+ return regExp.test(val)
+} */
+
+export function extractTimeLeft(now: Date, targetDate?: Date) {
+ if (!targetDate) {
+ return { hoursLeft: undefined, minutesLeft: undefined }
+ }
+ const deltaMilliseconds = targetDate.getTime() - now.getTime()
+ if (deltaMilliseconds <= 0) {
+ return { hoursLeft: undefined, minutesLeft: undefined }
+ }
+ const hours = Math.floor(deltaMilliseconds / 3.6e6)
+ const minutes = Math.floor(
+ (deltaMilliseconds - hours * 60 * 60 * 1000) / 60000
+ )
+ const hoursLeft = hours.toString()
+ const minutesLeft = minutes.toString()
+ return {
+ hoursLeft: hoursLeft,
+ minutesLeft: minutesLeft,
+ }
+}
+
+/**
+ * @param pos slider current pos
+ * @param width slider max width
+ * @returns a float number from 1 to 5
+ */
+export function getCrowdStatus(pos: number, width: number): number {
+ if (pos < 0) {
+ return 1
+ }
+ const percentage = pos / width
+
+ return 1 + percentage * 4
+}
+
+/**
+ * Return the correct end date in which the room is free given a record of occcupancies
+ *
+ * return undefined in case of errors
+ *
+ */
+export function getEndDate(startDate: Date, occupancies?: Occupancies) {
+ let time
+
+ if (occupancies !== undefined) {
+ try {
+ time = Object.keys(occupancies).find(time => {
+ const hour = parseInt(time.substring(0, 2))
+ const minutes = parseInt(time.substring(3))
+ return occupancies[`${hour}:${minutes}`] === "OCCUPIED"
+ })
+ } catch (err) {
+ console.log(err)
+ return undefined
+ }
+ }
+ if (time === undefined) {
+ const endDate = new Date(startDate)
+ endDate.setHours(20, 0, 0, 0)
+ return endDate
+ } else {
+ try {
+ const hour = parseInt(time.substring(0, 2))
+ const minutes = parseInt(time.substring(3))
+ const endDate = new Date(startDate)
+ endDate.setHours(hour, minutes, 0, 0)
+ return endDate
+ } catch (err) {
+ console.log(err)
+ return undefined
+ }
+ }
+}
+
+export function getBuildingCoords(campus: CampusItem, buildingName: string) {
+ for (const element of BuildingListJSON) {
+ if (element.acronym === campus.acronym) {
+ for (const c of element.campus) {
+ if (compareCampusNames(c.name, campus.name)) {
+ for (const b of c.buildings) {
+ if (b.name === buildingName) {
+ return b.coords
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+const compareCampusNames = (c1: string[], c2: string[]) => {
+ if (c1.length === c2.length) {
+ if (c1.length > 1) {
+ if (c1[0] === c2[0] && c1[1] === c2[1]) {
+ return true
+ } else {
+ return false
+ }
+ } else {
+ if (c1[0] === c2[0]) {
+ return true
+ } else {
+ return false
+ }
+ }
+ } else {
+ return false
+ }
+}