Membuat peta tematik di web dengan openlayers [Bagian 7: Kelas otomatis ]

Pada contoh-contoh sebelumnya kita menggunakan pengelompokan kelas yang kita definisikan sendiri. Hal ini tentunya sangat merepotkan jika kita meng handle banyak peta. Karenanya kita akan mencoba membuat kategori yang otomatis berdasarkan data. Algoritma yang paling sederhana adalah Equal Breaks, dimana hanya membagi range dari data dengan jumlah klasifikasi yang diinginkan. Berikut ini adalah contoh algoritma equal breaks:

function getEqualBreaks($data, $numclass){
	$breaks = array();

	$max = max($data);
	$min = min($data);
	$range = $max - $min;
	$step = intval($range / $numclass);

	for($i=0; $i < $numclass;$i++){
		$breaks[$i] = $min + ($step * ($i+1));
	}

	return $breaks;
}

Fungsi getEqualBreaks() ini akan dipanggil pada saat menentukan kelas. Parameter pertama merupakan array data dan parameter kedua adalah jumlah kelas yang diinginkan.

$bataskelas = getEqualBreaks($kepadatan, 4);

Untuk keperluan visualisasi legenda kita tambahkan kode html&php berikut di bawah peta:

<div id="legenda">
	Legenda:
	<table border="0">
		<?php
			for($i=0;$i<count($bataskelas);$i++)
			{
			?>
				<tr>
					<td bgcolor="<?php echo $warnakelas[$i] ?>" width="20px" height="20px"></td>
					<td width="10px"></td>
					<td>
						<?php
							if ($i == 0) echo "0 - ".($bataskelas[$i+1] - 1);
							else if ($i == count($bataskelas) - 1 ) echo "&ge; ".$bataskelas[$i];
							else echo ($bataskelas[$i])." - ".($bataskelas[$i+1] - 1);
						?>
					</td>
				</tr>
			<?php
			}
		?>
	</table>
</div>

Hasilnya yang didapat adalah seperti ini :

Terlihat bahwa dengan algoritma equal breaks hanya kelas pertama dan keempat yang ada “perwakilannya” di peta. Jadi peta nya kurang informatif. Untuk itu kita akan coba pakai algoritma yang lebih “advanced”. Yang paling sering dipakai adalah Algoritma Natural Breaks dari Jenks. openlayers tidak menyediakan algoritma ini sehingga kita harus mencari sendiri. Kita bisa coba mencontoh algoritma ini dari software-software GIS open source. Berikut ini adalah contoh implementasi algoritma natural breaks yang telah di-porting dari sofware GeoViz (berbasis Java) ke PHP:

function getJenksBreaks($data, $numclass){
	$numdata = count($data);

	// copy and sort the data
	$sorteddata = $data;
	sort($sorteddata);

	$mat1 = array();
	$mat2 = array();

	for ($i = 1; $i <= $numclass; $i++) {
		$mat1[1][$i] = 1;
		$mat2[1][$i] = 0;
		for ($j = 2; $j <= $numdata; $j++) {
			$mat2[$j][$i] = PHP_INT_MAX;
		}
	}

	$ssd = 0;
	for ($rangeEnd = 2; $rangeEnd <= $numdata; $rangeEnd++) {
		$sumX = 0;
		$sumX2 = 0;
		$w = 0;

		for ($m = 1; $m <= $rangeEnd; $m++) {
			$dataId = $rangeEnd - $m + 1;

			$val = $sorteddata[$dataId - 1];
			$sumX2 += $val * $val;
			$sumX += $val;
			$w++;
			$ssd = $sumX2 - ($sumX * $sumX) / $w;

			for ($j = 2; $j <= $numclass; $j++) {
				if (!($mat2[$rangeEnd][$j] < ($ssd + $mat2[$dataId - 1][$j - 1]))) {
					$mat1[$rangeEnd][$j] = $dataId;
					$mat2[$rangeEnd][$j] = $ssd + $mat2[$dataId - 1][$j - 1];
				}

			}

		}

		$mat1[$rangeEnd][1] = 1;
		$mat2[$rangeEnd][1] = $ssd;
	}

	$kbreaks = array();
	$kbreaks[$numclass - 1] = $sorteddata[$numdata - 1]; // the last break is the maximum value

	// break value is included in the lower class.
	$k = $numdata;
	for ($j = $numclass; $j >= 2; $j--) {
		$id = (int) ($mat1[$k][$j]) - 2;
		$kbreaks[$j - 2] = $sorteddata[$id];
		$k = (int) $mat1[$k][$j] - 1;
	}

	return $kbreaks;
}

Output dari fungsi ini adalah array kelas. namun format array-nya tidak berurutan, sehingga pada saat di encode ke json menjadi array associative di javascript nya. Untuk itu kita perlu memodifikasi variabel $bataskelas menjadi:

$bataskelas = getJenksBreaks($kepadatan, 4);
sort($bataskelas);
$bataskelas = array_map(
	create_function('$value', 'return (int)$value;'),
	$bataskelas
);

Hasil dari algoritma natural breaks adalah sebagai berikut:

Telihat bahwa peta kita kini jadi lebih berwarna. Namun demikian fungsi getJenksBreaks diatas mempunyai kelemahan. Yang pertama terkadang gagal mendapatkan nilai-nilai kelas yang diinginkan, ditandai dengan nilai breaks pertama yang berupa null atau terkadang 0. Kelemahan yang kedua adalah angka-angka hasil dari algoritma ini tidak “cantik”. Untuk memperbaiki kelemahan tersebut kita bisa menambahkan fungsi buatan kita sendiri untuk “memodifikasi” hasil dari algoritma natural breaks. Berikut ini adalah contohnya:

function getModifiedJenksBreaks($data, $numclass){
	$breaks = getJenksBreaks($data, $numclass);

	// if jenks failed, use equal
	if ($breaks[0] == null || $breaks[0] == 0){
		$breaks = getEqualBreaks($data, $numclass);
	}

	for($i=0; $i<$numclass; $i++){
		if ($i==0) $selisih = $breaks[$i+1] - $breaks[$i];
		else $selisih = $breaks[$i]-$breaks[$i-1];
		$slog = floor(log10($selisih));
		$breaks[$i] = round($breaks[$i], -$slog);
	}

	return $breaks;
}

Fungsi diatas berguna untuk mengganti ke equal breaks jika jenks breaks gagal, dan juga memodifikasi nilai-nilai agar terlihat “lebih cantik” dengan cara pembulatan angka. Hasil dari algoritma ini adalah sebagai berikut:

Terlihat bahwa angka-anga nya berupa angka-angka bulat dan persebaran warna nya masih ada, walaupun kadang kala pada data tertentu ada beberapa warna yang hilang.

6 thoughts on “Membuat peta tematik di web dengan openlayers [Bagian 7: Kelas otomatis ]

  1. wah… ini dia yang saya cari, mas kalo kita mau select per region, pake open layer gmn ya mas? saya baca2 biar bisa di select atau di hover, itu harus vector, tapi ngeload layer vector berdasarkan file shp provinsinya gagal terus, hehe. mohon pencerahannya y mas 🙂

    1. makasih mas, kunjungannya,
      maksudnya apa bikin popup gt ya? kalau saya pernah pake event select. seperti di website sp2010.bps.go.id . apa seperti itu yang mas maksudkan? kalau iya, di web itu kan bisa dilihat javascriptnya untuk dipelajari. 🙂

  2. Asslamualaikum wr.wb.
    Mas kala buat point gimna?
    contohnya kan hanya polygon aja…
    tolong informasinya…
    soalnya saya mau coba buat peta sebaran sekolah yang databasenya bisa di update langsung lewat webnya…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s