1 Στόχοι της άσκησης

  • Διάβασμα Shapefile αρχείων με χρηση σχετικού path
  • Φιλτράρισμα γεωγραφικών δεδομένων
  • Υποσυνολο γεωγραφικών δεδομένων
  • Μετατροπή Vector σε Raster
  • Υπολογισμός αποστασης σε δεδομένα Raster
  • Εξαγωγή σημειακών τιμών απο δεδομένα Raster
  • Ιεράρχηση (Ranking) γεωγραφικών δεδομένων
  • Στάθμιση (Weighting) γεωγραφικών δεδομένων
  • Βασική ανάλυση καταληλότητας γεωγραφικών θέσεων

2 Δεδομένα

Φορτώνουμε τις απαραίτητες βιβλιοθήκες καθώς και τα δεδομένα. Φορτώνοντας τα δεδομένα, αναθέτουμε και προβολικό σύστημα συντεταγμένων (CRS).

library(sf)
library(tibble)
library(raster)

ghsl_crs_text = '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs'
ghsl_crs = 4326

spitia = sf::read_sf( "data/Spitia.shp" ) %>% sf::st_transform(ghsl_crs)
schools = sf::read_sf( "data/Sxoleia.shp" ) %>% sf::st_transform(ghsl_crs)
metro = sf::read_sf( "data/Metro.shp" ) %>% sf::st_transform(ghsl_crs)
perioxi = sf::read_sf( "data/perioxi.shp" ) %>% sf::st_transform(ghsl_crs)

Εδώ είναι όλες οι λεπτομέρειες για τα διαθέσιμα σπίτια στην περιοχή. Αυτός είναι στην πραγματικότητα ο Πίνακας Χαρακτηριστικών του Shapefile. Μετατρέπουμε επίσης τη στήλη Price από String σε Numeric για περαιτέρω ανάλυση.

spitia %>% st_drop_geometry() %>% as.data.frame()
   Price  ID
1   1200 A01
2    700 A02
3    900 A03
4    890 A04
5    750 A05
6   1500 A06
7    880 A07
8    800 A08
9    920 A09
10   990 A10
11   900 A11
12   940 A12
13   970 A13
14   800 Α14
15   980 Α15
16   700 Α16
17   600 Α17
18   800 Α18
19   970 Α19
20  1400 Α20
21   890 Α21
22   930 Α22
23   690 Α23
24   780 Α24
25   890 Α25
26   500 Α26
27   930 Α27
28   910 Α28
29   940 Α29
30   800 Α30

Μετατροπή της στήλης Price από String σε Numeric, για να τη χρησιμοποιήσουμε αργότερα.

spitia$Price = as.numeric(spitia$Price)

3 Υποσύνολο

Επιλογή φθηνού σπιτιού με ενοίκιο μέχρι $1000.

spitia2 = subset(spitia, spitia$Price < 1000)

excluded = spitia$ID[!(spitia$ID %in% spitia2$ID)]

spitia2 %>% st_drop_geometry() %>% as.data.frame()
   Price  ID
1    700 A02
2    900 A03
3    890 A04
4    750 A05
5    880 A07
6    800 A08
7    920 A09
8    990 A10
9    900 A11
10   940 A12
11   970 A13
12   800 Α14
13   980 Α15
14   700 Α16
15   600 Α17
16   800 Α18
17   970 Α19
18   890 Α21
19   930 Α22
20   690 Α23
21   780 Α24
22   890 Α25
23   500 Α26
24   930 Α27
25   910 Α28
26   940 Α29
27   800 Α30
par(mar = c(0, 1, 2, 1))
plot(st_geometry(perioxi), main="Υποσύνολο σπιτιών")
plot(st_geometry(spitia), col="red", pch=0,  cex=0.9, add=T)
text(st_coordinates(spitia), label=spitia$ID, pos=2, col="red", offset=0.4)

plot(st_geometry(spitia2), col="blue", pch=15,add=T)
text(st_coordinates( spitia2), label=spitia2$ID, pos=2, col="blue", offset=0.4)
legend("topleft", legend = c("Σπίτια", "Εξαιρούμενα σπίτια"), pch=c(15,0), col=c("blue","red" )  )

Μετατροπή του πολυγώνου της περιοχής μελέτης σε Raster ώστε να χρησιμοποιηθεί αργότερα για τους υπολογισμούς αποστάσεων.

r_temp = raster(ncol=20, nrow=20)
extent(r_temp) = extent(perioxi)
r = rasterize(perioxi, r_temp, field=0 )
#crs(r) = CRS(ghsl_crs_text)

Οπτικοποίηση όλων των δεδομένων μέχρι εδώ:

par(mar=c(0,1,2,1))
plot(rasterToPolygons(r), border="grey")
plot(st_geometry(spitia2), add=T, pch=15, cex=1)
plot(st_geometry(schools), add=T, pch=17, cex=1, col="red")
plot(st_geometry(metro), add=T, pch=9, cex=1, col="blue")
plot(st_geometry(perioxi), add=T)
legend("topleft", legend = c("Σπίτια", "Σχολεία","ΜΕΤΡΟ"), pch=c(15,17,9), col=c("black","red","blue")  )

4 Απόσταση

Για κάθε ένα από τα 27 σπίτια (spitia2) θέλουμε να υπολογίσουμε την απόσταση του προς Σχολεία και προς ΜΕΤΡΟ.

Αυτή η διαδικασία θα παράγει 2 Raster τιμές απόστασης σε μέτρα (προς Σχολεία και προς ΜΕΤΡΟ).

Μετά, θα εξάγουμε (extract) τιμές από αυτά τα 2 Raster για κάθε σπίτι.

distances_school = raster::mask( raster::distanceFromPoints(object = r, xy = schools),  r) # 1st raster
distances_school
class      : RasterLayer 
dimensions : 20, 20, 400  (nrow, ncol, ncell)
resolution : 0.1953293, 0.1290997  (x, y)
extent     : -1.556565, 2.350021, -0.9352757, 1.646718  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +datum=WGS84 +no_defs 
source     : memory
names      : layer 
values     : 1115.647, 269630.9  (min, max)
plot(distances_school, main="Απόσταση από Σχολεία")
plot(st_geometry(spitia2), add=T, pch=21, cex=2)
plot(st_geometry(schools), add=T, pch=12, cex=2, col="red")

Ανάθεση των τιμών “απόστασης” σε μια νέα στήλη DistanceToSchools για κάθε σπίτι. Η τιμή της απόστασης διαιρείτε με 1000 ώστε να μετατραπεί από μέτρα σε χιλιόμετρα.

spitia2$DistanceToSchools = raster::extract(distances_school, spitia2)/1000

Υπολογισμός απόστασης από ΜΕΤΡΟ.

distances_metro = raster::mask( raster::distanceFromPoints(object = r, xy = metro),  r) # 2nd raster
distances_metro
class      : RasterLayer 
dimensions : 20, 20, 400  (nrow, ncol, ncell)
resolution : 0.1953293, 0.1290997  (x, y)
extent     : -1.556565, 2.350021, -0.9352757, 1.646718  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +datum=WGS84 +no_defs 
source     : memory
names      : layer 
values     : 6837.832, 150723.8  (min, max)
plot(distances_metro, main="Απόσταση από ΜΕΤΡΟ")
plot(st_geometry(spitia2), add=T, pch=21, cex=2)
plot(st_geometry(metro), add=T, pch=9, cex=2, col="blue")

Ανάθεση των τιμών “απόστασης” σε μια νέα στήλη DistanceToMETRO για κάθε σπίτι. Η τιμή της απόστασης διαιρείτε με 1000 ώστε να μετατραπεί από μέτρα σε χιλιόμετρα.

spitia2$DistanceToMETRO = raster::extract(distances_metro, spitia2)/1000

Το “Attribute Table” των σπιτιών μέχρι στιγμής:

spitia2  %>% st_drop_geometry() %>% as.data.frame()
   Price  ID DistanceToSchools DistanceToMETRO
1    700 A02         43.932309        77.44777
2    900 A03          6.699126        51.53105
3    890 A04         50.739982       107.73805
4    750 A05         32.458905        78.86374
5    880 A07         46.259821        26.74466
6    800 A08         90.090958        37.24592
7    920 A09         27.443844        79.25847
8    990 A10         97.109540        80.89853
9    900 A11         66.407636        25.20784
10   940 A12         26.519606        57.01930
11   970 A13         35.005569        24.99546
12   800 Α14         98.819344       129.43813
13   980 Α15        172.538332       132.17557
14   700 Α16        189.027717        82.51040
15   600 Α17        250.372879        87.16461
16   800 Α18        267.477192       103.41649
17   970 Α19        197.780764        63.23588
18   890 Α21        128.358799       131.50512
19   930 Α22        179.371294        27.35128
20   690 Α23        136.979236        35.14003
21   780 Α24         95.576929        74.18805
22   890 Α25         57.349590        37.10294
23   500 Α26         77.309857        51.77192
24   930 Α27        111.699274        79.11142
25   910 Α28         70.269046       106.50194
26   940 Α29         90.676296       138.22636
27   800 Α30         76.448847       106.32168

5 Ιεράρχηση (Ranking)

Θέλουμε να ιεραρχήσουμε όλα τα σπίτια με βάση τις προτιμήσεις των πελατών σχετικά με αποστάσεις προς Σχολεία και ΜΕΤΡΟ. Σε κάθε σπίτι θα φτιάξουμε 2 νέες στήλες: SchoolsRank και METRORank όπου θα αποθηκεύσουμε το αποτέλεσμα της ιεράρχησης.

Οι πελάτες προτιμούν να είναι κοντά σε Σχολείο (μικρές τιμές απόστασης):

spitia2$SchoolsRank = rank(- spitia2$DistanceToSchools)

Οι πελάτες προτιμούν να είναι μακριά από ΜΕΤΡΟ (μεγάλες τιμές απόστασης):

spitia2$METRORank = rank(spitia2$DistanceToMETRO)

Το “Attribute Table” των σπιτιών μέχρι στιγμής:

spitia2 %>% st_drop_geometry() %>%  as.data.frame()
   Price  ID DistanceToSchools DistanceToMETRO SchoolsRank METRORank
1    700 A02         43.932309        77.44777          22        13
2    900 A03          6.699126        51.53105          27         8
3    890 A04         50.739982       107.73805          20        23
4    750 A05         32.458905        78.86374          24        14
5    880 A07         46.259821        26.74466          21         3
6    800 A08         90.090958        37.24592          14         7
7    920 A09         27.443844        79.25847          25        16
8    990 A10         97.109540        80.89853          11        17
9    900 A11         66.407636        25.20784          18         2
10   940 A12         26.519606        57.01930          26        10
11   970 A13         35.005569        24.99546          23         1
12   800 Α14         98.819344       129.43813          10        24
13   980 Α15        172.538332       132.17557           6        26
14   700 Α16        189.027717        82.51040           4        18
15   600 Α17        250.372879        87.16461           2        19
16   800 Α18        267.477192       103.41649           1        20
17   970 Α19        197.780764        63.23588           3        11
18   890 Α21        128.358799       131.50512           8        25
19   930 Α22        179.371294        27.35128           5         4
20   690 Α23        136.979236        35.14003           7         5
21   780 Α24         95.576929        74.18805          12        12
22   890 Α25         57.349590        37.10294          19         6
23   500 Α26         77.309857        51.77192          15         9
24   930 Α27        111.699274        79.11142           9        15
25   910 Α28         70.269046       106.50194          17        22
26   940 Α29         90.676296       138.22636          13        27
27   800 Α30         76.448847       106.32168          16        21

6 Στάθμιση (Weighting)

Οι πελάτες έχουν ορίσει μια στάθμιση για τα 2 κριτήρια τους:

  • 60% κοντά σε σχολεία

  • 40% μακριά από ΜΕΤΡΟ

Τους ενδιαφέρει δηλαδή πιο πολύ να είναι κοντά σε σχολεία.

Κατασκευάζουμε μια νέα στήλη decision η οποία θα δείχνει την συνολική καταλληλότητα για κάθε σπίτι σύμφωνα με τη παραπάνω στάθμιση :

spitia2$decision = (spitia2$SchoolsRank * 0.6) + (spitia2$METRORank * 0.4)

7 Απόφαση

Το σπίτι με την μεγαλύτερη καταλληλότητα (decision), είναι το ακόλουθο:

solution = spitia2[spitia2$decision==max(spitia2$decision),]

spitia2[spitia2$ID==solution$ID,] %>% st_drop_geometry() %>% as.data.frame()
  Price  ID DistanceToSchools DistanceToMETRO SchoolsRank METRORank decision
1   920 A09          27.44384        79.25847          25        16     21.4

Είναι δηλαδή το σπίτι με ID=A09

spitia2 %>% st_drop_geometry() %>% as.data.frame()
   Price  ID DistanceToSchools DistanceToMETRO SchoolsRank METRORank decision
1    700 A02         43.932309        77.44777          22        13     18.4
2    900 A03          6.699126        51.53105          27         8     19.4
3    890 A04         50.739982       107.73805          20        23     21.2
4    750 A05         32.458905        78.86374          24        14     20.0
5    880 A07         46.259821        26.74466          21         3     13.8
6    800 A08         90.090958        37.24592          14         7     11.2
7    920 A09         27.443844        79.25847          25        16     21.4
8    990 A10         97.109540        80.89853          11        17     13.4
9    900 A11         66.407636        25.20784          18         2     11.6
10   940 A12         26.519606        57.01930          26        10     19.6
11   970 A13         35.005569        24.99546          23         1     14.2
12   800 Α14         98.819344       129.43813          10        24     15.6
13   980 Α15        172.538332       132.17557           6        26     14.0
14   700 Α16        189.027717        82.51040           4        18      9.6
15   600 Α17        250.372879        87.16461           2        19      8.8
16   800 Α18        267.477192       103.41649           1        20      8.6
17   970 Α19        197.780764        63.23588           3        11      6.2
18   890 Α21        128.358799       131.50512           8        25     14.8
19   930 Α22        179.371294        27.35128           5         4      4.6
20   690 Α23        136.979236        35.14003           7         5      6.2
21   780 Α24         95.576929        74.18805          12        12     12.0
22   890 Α25         57.349590        37.10294          19         6     13.8
23   500 Α26         77.309857        51.77192          15         9     12.6
24   930 Α27        111.699274        79.11142           9        15     11.4
25   910 Α28         70.269046       106.50194          17        22     19.0
26   940 Α29         90.676296       138.22636          13        27     18.6
27   800 Α30         76.448847       106.32168          16        21     18.0

Τελική οπτικοποίηση του πιο κατάλληλου σπιτιού:

plot(st_geometry(perioxi) )
plot(st_geometry(spitia2), pch=15, cex=1, main="Final Decision", add=T)
plot(st_geometry(solution), pch=21, cex=2, add=T)
plot(st_geometry(schools), add=T, pch=17, cex=2, col="red")
plot(st_geometry(metro), add=T, pch=9, cex=2, col="blue")
box()
text(st_coordinates(spitia2[spitia2$decision==max(spitia2$decision),]), label="solution", pos=4)
text(st_coordinates(spitia2), label=spitia2$ID, pos=2, col="darkgreen", offset=0.4)
legend("topleft", legend = c("Σπίτια", "Σχολεία","ΜΕΤΡΟ"), pch=c(15,17,9), col=c("black","red","blue")  )

8 Αναφορά

Κατεβάστε το zip αρχείο “01_RealEstate.zip” και αφού το αποσυμπιέσετε, χρησιμοποιήστε το Script που περιλαμβάνει μέσα ώστε να ξεκινήσετε την ανάλυση σας. Ετοιμάστε μια αναφορά σε ένα αρχείο PDF η οποία να απαντά σε όλα τα παρακάτω ερωτήματα υποδεικνύοντας: κώδικα, κείμενο, γραφήματα ή/και χάρτες.

Α1.1: Ποιό σπίτι είναι το δεύτερο καταλληλότερο και πιο το λιγότερο κατάλληλο?

Α1.2: Ποιό σπίτι είναι το καταλληλότερο αν τα κριτήρια των πελατών ήταν τα ακόλουθα:

  • 30% μακριά από σχολεία

  • 60% κοντά από ΜΕΤΡΟ