CartoWeb добавление кодировок cp1251, koi8-r и других

Mapserver, GeoServer, MapGuide, Google и другое ПО для веб-картографии
Ответить
john
Новоприбывший
Сообщения: 4
Зарегистрирован: 15 май 2008, 06:30
Репутация: 0

CartoWeb добавление кодировок cp1251, koi8-r и других

Сообщение john » 24 янв 2009, 11:55

Небольшое предисловие.
Как-то вот занялся установкой и настройкой MapServer, и выбрал CartoWeb.
Хотелось руссификации, а она не работает, вернее после написания файлов
перевода .MO в кодировке utf8 и сборки, сайт стал "говорить" по-русски.
НО shape-файлы, а вернее таблицы .dbf из ArcView и поэтому, в Windows,
по-умолчанию используют cp1251 :(. После долгих поисков нашел
сообщение пользователя на форуме CartoWeb Users и решил попробовать сделать так же.
Вот представляю результат.

Изначально CartoWeb поддерживает только перекодировку ISO-8859-1 <-> UTF-8.
Перекодировка осуществляется встроенными функциями php utf_encode() и utf_decode().
Вызывается в модуле: ms4w\apps\cartoweb3\common\Encoding.php.
В модуле создаютя классы EncodeUTF и EncodeISO, которые соответствуют кодировкам utf-8 и ISO-8859-1.
Для перекодировки cp1251 <-> utf-8 создаем дополнительный класс в CARTOWEB_HOME\common\Encode.php, например EncodeCP1251,
простым копированием класса EncodeISO:

Код: Выделить всё

*
* ISO-8859-1 en/decoder
* @package Client
*/
class EncoderISO implements EncoderInterface {

/**
* @see EncoderInterface::encode()
*/
public function encode($text) {
if (is_array($text)) {
$result = array();
foreach ($text as $key => $value) {
$result[utf8_encode($key)] = utf8_encode($value);
}
return $result;
}
return utf8_encode($text);
}

/**
* @see EncoderInterface::decode()
*/
public function decode($text) {
if (is_array($text)) {
$result = array();
foreach ($text as $key => $value) {
$result[utf8_decode($key)] = utf8_decode($value);
}
return $result;
}
return utf8_decode($text);
}

/**
* @see EncoderInterface::getCharset()
*/
public function getCharset() {
return 'iso-8859-1';
}
}
Затем заменяем ф-ции utf_encode() и utf_decode() на ф-ции осуществляющие перекодировку
cp1251 -> utf-8: например cp1251_2_utf8(), и utf8 -> cp1251: например
utf8_2_cp1251():

Код: Выделить всё

/**
* CP1251 ru/decoder
* @package Client
*/
function cp1251_2_utf8($str,$isTo = true)
{
$arr = array('ё'=>'ё','Ё'=>'Ё');
for($i=192;$i<256;$i++)
$arr[chr($i)] = '____'.dechex($i-176).';';
$str =preg_replace(array('@([а-я]) @i','@ ([а-я])@i'),array('$1 ',' $1'),$str);
return strtr($str,$isTo?$arr:array_flip($arr));
}

function utf8_2_cp1251($s)
{
$out="";$c1="";$byte2=false;
for ($c=0;$c {
$i=ord($s[$c]);
if ($i<=127) $out.=$s[$c];
if ($byte2)
{
$new_c2=($c1&3)*64+($i&63);
$new_c1=($c1>>2)&5;
$new_i=$new_c1*256+$new_c2;
if ($new_i==1025) $out_i=168; 
else
if ($new_i==1105) $out_i=184;
else $out_i=$new_i-848;
$out.=chr($out_i);
$byte2=false;
}
if (($i>>5)==6) {$c1=$i;$byte2=true;}
}
return $out;
}

class EncoderCP1251 implements EncoderInterface {

/**
* @see EncoderInterface::encode()
*/

public function encode($text) {


if (is_array($text)) {
$result = array();
foreach ($text as $key => $value) {
$result[cp1251_2_utf8($key)] = cp1251_2_utf8($value);
}
return $result;
}
return cp1251_2_utf8($text);

}

/**
* @see EncoderInterface::decode()
*/

public function decode($text) {


if (is_array($text)) {
$result = array();
foreach ($text as $key => $value) {
$result[utf8_2_cp1251($key)] = utf8_2_cp1251($value);
}
return $result;
}
return utf8_2_cp1251($text);
}

/**
* @see EncoderInterface::getCharset()
*/
public function getCharset() {
return 'cp1251';
}
}
Поскольку в PHP я не силен, то воспользовался поиском и нашел такие вот ф-ции:
функция для перекодировки cp1251 -> utf-8 взята с http://ru.php.net/utf8_decode:
bn2 (bn2 at ukr dot net)
01-Sep-2003 07:56
Function to decode uft8 to win-1251 (russian) charset. Don't support ukrainian letters. Support only 2-byte coding.

Код: Выделить всё

function utf8win1251($s){...
Функция для перекодировки utf-8 -> win1251 взята с http://ru.php.net/utf8_encode:
nikooo adog bk adot ru - Nickolaz
03-May-2007 06:02
You can use this simple code to convert win-1251 into Unicode.

Код: Выделить всё

function rus2uni($str,$isTo = true)
{...
Теперь в настройках проекта и CartoWeb'а можно использовать
дополнительный класс кодировщика -- EncoderCP1251

Второй метод, поскольку первый меня не устроил, хотелось реализовать еще и cp866:

Так же есть класс для PHP UTF8, созданный Alexander Minkovsky,
для кодировок:
CP874, CP932, CP936, CP949, CP950, CP1250, CP1251,
CP1252, CP1253, CP1254, CP1255, CP1256, CP1257, CP1258.
Этот класс использует map-файлы с сопоставлением символов, поэтому легко можно дописать нужный map и дополнить класс нужной кодовой страницей.

распаковал класс utf-8 в каталог "CARTOWEB_HOME\common" и соотв-но изменил каталог расположения map-файлов в файле utf8.class.php:

Код: Выделить всё

define("MAP_DIR",CARTOWEB_HOME . "common");
создал и добавил в этот же каталог два map-файла:

Код: Выделить всё

define("CP866", MAP_DIR . "/CP866.MAP");
define("koi8r", MAP_DIR . "/koi8r.MAP");
map-файлы сделал из wiki: cp866 и koi8-r

cp866 (от 0x00 до 0x7F можно взять из cp1250):

Код: Выделить всё

0x80	0x0410	#	Ђ
0x81	0x0411	#	Ѓ
0x82	0x0412	#	‚
0x83	0x0413	#	ѓ
0x84	0x0414	#	„
0x85	0x0415	#	…
0x86	0x0416	#	†
0x87	0x0417	#	‡
0x88	0x0418	#	€
0x89	0x0419	#	‰
0x8A	0x041A	#	Љ
0x8B	0x041B	#	‹
0x8C	0x041C	#	Њ
0x8D	0x041D	#	Ќ
0x8E	0x041E	#	Ћ
0x8F	0x041F	#	Џ
0x90	0x0420	#	ђ
0x91	0x0421	#	‘
0x92	0x0422	#	’
0x93	0x0423	#	“
0x94	0x0424	#	”
0x95	0x0425	#	•
0x96	0x0426	#	–
0x97	0x0427	#	—
0x98	0x0428	#	_____
0x99	0x0429	#	™
0x9A	0x042A	#	љ
0x9B	0x042B	#	›
0x9C	0x042C	#	њ
0x9D	0x042D	#	ќ
0x9E	0x042E	#	ћ
0x9F	0x042F	#	џ
0xA0	0x0430	#	 
0xA1	0x0431	#	Ў
0xA2	0x0432	#	ў
0xA3	0x0433	#	Ј
0xA4	0x0434	#	¤
0xA5	0x0435	#	Ґ
0xA6	0x0436	#	¦
0xA7	0x0437	#	§
0xA8	0x0438	#	Ё
0xA9	0x0439	#	©
0xAA	0x043A	#	Є
0xAB	0x043B	#	«
0xAC	0x043C	#	¬
0xAD	0x043D	#	­
0xAE	0x043E	#	®
0xAF	0x043F	#	Ї
0xB0	0x2591	#	-
0xB1	0x2592	#	-
0xB2	0x2593	#	-
0xB3	0x2502	#	і
0xB4	0x2524	#	+
0xB5	0x2561	#	і
0xB6	0x2562	#	і
0xB7	0x2556	#	ї
0xB8	0x2555	#	ї
0xB9	0x2563	#	і
0xBA	0x2551	#	і
0xBB	0x2557	#	ї
0xBC	0x255D	#	-
0xBD	0x255C	#	-
0xBE	0x255B	#	-
0xBF	0x2510	#	ї
0xC0	0x2514	#	L
0xC1	0x2534	#	+
0xC2	0x252C	#	T
0xC3	0x251C	#	+
0xC4	0x2500	#	-
0xC5	0x253C	#	+
0xC6	0x255E	#	і
0xC7	0x255F	#	і
0xC8	0x255A	#	L
0xC9	0x2554	#	Ј
0xCA	0x2569	#	і
0xCB	0x2566	#	T
0xCC	0x2560	#	і
0xCD	0x2550	#	=
0xCE	0x256C	#	+
0xCF	0x2567	#	і
0xD0	0x2568	#	і
0xD1	0x2564	#	T
0xD2	0x2565	#	T
0xD3	0x2559	#	L
0xD4	0x2558	#	L
0xD5	0x2552	#	-
0xD6	0x2553	#	Ј
0xD7	0x256B	#	+
0xD8	0x256A	#	+
0xD9	0x2518	#	-
0xDA	0x250C	#	-
0xDB	0x2588	#	-
0xDC	0x2584	#	-
0xDD	0x258C	#	і
0xDE	0x2590	#	і
0xDF	0x2580	#	-
0xE0	0x0440	#	а
0xE1	0x0441	#	б
0xE2	0x0442	#	в
0xE3	0x0443	#	г
0xE4	0x0444	#	д
0xE5	0x0445	#	е
0xE6	0x0446	#	ж
0xE7	0x0447	#	з
0xE8	0x0448	#	и
0xE9	0x0449	#	й
0xEA	0x044A	#	к
0xEB	0x044B	#	л
0xEC	0x044C	#	м
0xED	0x044D	#	н
0xEE	0x044E	#	о
0xEF	0x044F	#	п
0xF0	0x0401	#	р
0xF1	0x0451	#	с
0xF2	0x0404	#	т
0xF3	0x0454	#	у
0xF4	0x0407	#	ф
0xF5	0x0457	#	х
0xF6	0x040E	#	ц
0xF7	0x045E	#	ч
0xF8	0x00B0	#	ш
0xF9	0x2219	#	_____
0xFA	0x00B7	#	ъ
0xFB	0x221A	#	v
0xFC	0x2116	#	ь
0xFD	0x00A4	#	э
0xFE	0x25A0	#	і
0xFF	0x00A0	#	 
koi8-r (аналогично cp866):

Код: Выделить всё

0x80	0x2500	#	-
0x81	0x2502	#	¦
0x82	0x250C	#	-
0x83	0x2510	#	¬
0x84	0x2514	#	L
0x85	0x2518	#	-
0x86	0x251C	#	+
0x87	0x2524	#	+
0x88	0x252C	#	T
0x89	0x2534	#	+
0x8A	0x253C	#	+
0x8B	0x2580	#	-
0x8C	0x2584	#	-
0x8D	0x2588	#	-
0x8E	0x258C	#	¦
0x8F	0x2590	#	¦
0x90	0x2591	#	-
0x91	0x2592	#	-
0x92	0x2593	#	-
0x93	0x2320	#	?
0x94	0x25A0	#	¦
0x95	0x2219	#	•
0x96	0x221A	#	v
0x97	0x2248	#	?
0x98	0x2264	#	?
0x99	0x2265	#	?
0x9A	0x00A0	#	 
0x9B	0x2321	#	?
0x9C	0x00B0	#	°
0x9D	0x00B2	#	?
0x9E	0x00B7	#	·
0x9F	0x00F7	#	?
0xA0	0x2550	#	=
0xA1	0x2551	#	¦
0xA2	0x2552	#	-
0xA3	0x0451	#	ё
0xA4	0x2553	#	г
0xA5	0x2554	#	г
0xA6	0x2555	#	¬
0xA7	0x2556	#	¬
0xA8	0x2557	#	¬
0xA9	0x2558	#	L
0xAA	0x2559	#	L
0xAB	0x255A	#	L
0xAC	0x255B	#	-
0xAD	0x255C	#	-
0xAE	0x255D	#	-
0xAF	0x255E	#	¦
0xB0	0x255F	#	¦
0xB1	0x2560	#	¦
0xB2	0x2561	#	¦
0xB3	0x0401	#	Ё
0xB4	0x2562	#	¦
0xB5	0x2563	#	¦
0xB6	0x2564	#	T
0xB7	0x2565	#	T
0xB8	0x2566	#	T
0xB9	0x2567	#	¦
0xBA	0x2568	#	¦
0xBB	0x2569	#	¦
0xBC	0x256A	#	+
0xBD	0x256B	#	+
0xBE	0x256C	#	+
0xBF	0x00A9	#	©
0xC0	0x044E	#	ю
0xC1	0x0430	#	а
0xC2	0x0431	#	б
0xC3	0x0446	#	ц
0xC4	0x0434	#	д
0xC5	0x0435	#	е
0xC6	0x0444	#	ф
0xC7	0x0433	#	г
0xC8	0x0445	#	х
0xC9	0x0438	#	и
0xCA	0x0439	#	й
0xCB	0x043A	#	к
0xCC	0x043B	#	л
0xCD	0x043C	#	м
0xCE	0x043D	#	н
0xCF	0x043E	#	о
0xD0	0x043F	#	п
0xD1	0x044F	#	я
0xD2	0x0440	#	р
0xD3	0x0441	#	с
0xD4	0x0442	#	т
0xD5	0x0443	#	у
0xD6	0x0436	#	ж
0xD7	0x0432	#	в
0xD8	0x044C	#	ь
0xD9	0x044B	#	ы
0xDA	0x0437	#	з
0xDB	0x0448	#	ш
0xDC	0x044D	#	э
0xDD	0x0449	#	щ
0xDE	0x0447	#	ч
0xDF	0x044A	#	ъ
0xE0	0x042E	#	Ю
0xE1	0x0410	#	А
0xE2	0x0411	#	Б
0xE3	0x0426	#	Ц
0xE4	0x0414	#	Д
0xE5	0x0415	#	Е
0xE6	0x0424	#	Ф
0xE7	0x0413	#	Г
0xE8	0x0425	#	Х
0xE9	0x0418	#	И
0xEA	0x0419	#	Й
0xEB	0x041A	#	К
0xEC	0x041B	#	Л
0xED	0x041C	#	М
0xEE	0x041D	#	Н
0xEF	0x041E	#	О
0xF0	0x041F	#	П
0xF1	0x042F	#	Я
0xF2	0x0420	#	Р
0xF3	0x0421	#	С
0xF4	0x0422	#	Т
0xF5	0x0423	#	У
0xF6	0x0416	#	Ж
0xF7	0x0412	#	В
0xF8	0x042C	#	Ь
0xF9	0x042B	#	Ы
0xFA	0x0417	#	З
0xFB	0x0428	#	Ш
0xFC	0x042D	#	Э
0xFD	0x0429	#	Щ
0xFE	0x0427	#	Ч
0xFF	0x042A	#	Ъ
Теперь снова залез в "CARTOWEB_HOME\common\Encode.php" и создал три класса EncodeCP1251, EncodeCP866 и EncodeKOI8R:

EncodeCP1251:

Код: Выделить всё

/**
 * CP1251 ru/decoder
 * @package Client
 */
class EncoderCP1251 implements EncoderInterface {

	private static $utfConverter;
	function __construct() {
		self::$utfConverter = new utf8(CP1251);
	}
	
    /**
     * @see EncoderInterface::encode()
     */
    public function encode($text) {
        if (is_array($text)) {
            $result = array();
            foreach ($text as $key => $value) {
                $result[self::$utfConverter->strToUtf8($key)] = self::$utfConverter->strToUtf8($value);
            }
            return $result;
        }
        return self::$utfConverter->strToUtf8($text);
    }

    /**
     * @see EncoderInterface::decode()
     */
    public function decode($text) {
        if (is_array($text)) {
            $result = array();
            foreach ($text as $key => $value) {
                $result[self::$utfConverter->utf8ToStr($key)] = self::$utfConverter->utf8ToStr($value);
            }
            return $result;
        }
        return self::$utfConverter->utf8ToStr($text);
    }
    
    /**
     * @see EncoderInterface::getCharset()
     */
    public function getCharset() {
        return 'cp1251';
    }
}
EncodeCP866:

Код: Выделить всё

/**
 * CP866 ru/decoder
 * @package Client
 */
class EncoderCP866 implements EncoderInterface {

	private static $utfConverter;
	function __construct() {
		self::$utfConverter = new utf8(CP866);
	}
	
    /**
     * @see EncoderInterface::encode()
     */
    public function encode($text) {
        if (is_array($text)) {
            $result = array();
            foreach ($text as $key => $value) {
                $result[self::$utfConverter->strToUtf8($key)] = self::$utfConverter->strToUtf8($value);
            }
            return $result;
        }
        return self::$utfConverter->strToUtf8($text);
    }

    /**
     * @see EncoderInterface::decode()
     */
    public function decode($text) {
        if (is_array($text)) {
            $result = array();
            foreach ($text as $key => $value) {
                $result[self::$utfConverter->utf8ToStr($key)] = self::$utfConverter->utf8ToStr($value);
            }
            return $result;
        }
        return self::$utfConverter->utf8ToStr($text);
    }
    
    /**
     * @see EncoderInterface::getCharset()
     */
    public function getCharset() {
        return 'cp866';
    }
}
EncodeKOI8R:

Код: Выделить всё

/**
 * koi8r ru/decoder
 * @package Client
 */
class EncoderKOI8R implements EncoderInterface {

	private static $utfConverter;
	function __construct() {
		self::$utfConverter = new utf8(koi8r);
	}
	
    /**
     * @see EncoderInterface::encode()
     */
    public function encode($text) {
        if (is_array($text)) {
            $result = array();
            foreach ($text as $key => $value) {
                $result[self::$utfConverter->strToUtf8($key)] = self::$utfConverter->strToUtf8($value);
            }
            return $result;
        }
        return self::$utfConverter->strToUtf8($text);
    }

    /**
     * @see EncoderInterface::decode()
     */
    public function decode($text) {
        if (is_array($text)) {
            $result = array();
            foreach ($text as $key => $value) {
                $result[self::$utfConverter->utf8ToStr($key)] = self::$utfConverter->utf8ToStr($value);
            }
            return $result;
        }
        return self::$utfConverter->utf8ToStr($text);
    }
    
    /**
     * @see EncoderInterface::getCharset()
     */
    public function getCharset() {
        return 'koi8-r';
    }
}
Все, :) теперь можно использовать новые классы Encode (правда проверил пока только cp1251): EncodeCP1251, EncodeCP866 и EncodeKOI8R.

Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9129
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 748
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: CartoWeb добавление кодировок cp1251, koi8-r и других

Сообщение Максим Дубинин » 24 янв 2009, 19:20

большое спасибо, что делитесь опытом, очень радует

небольшая проблема, мне пришлось в коде вашего сообщения заменить в 3-4 местах несколько символов на "____", иначе не валидировался rss-форума. Пожалуйста, имейте в виду, возможно стоит приложить весь код разом в варианте для скачки?
пристегивайтесь, турбулентность прямо по курсу

john
Новоприбывший
Сообщения: 4
Зарегистрирован: 15 май 2008, 06:30
Репутация: 0

Re: CartoWeb добавление кодировок cp1251, koi8-r и других

Сообщение john » 26 янв 2009, 06:16

Хорошо, прикладываю :) архив с дополненным классом utf8 и поправленным Encoding.php. Архив распаковать в каталог "CartoWeb_Home/common/" и в конфигурации можно использовать 3 новых класса EncoderCP1251, EncoderCP866 и EncoderKOI8R.
Вложения
utf8.zip
архив с классом php utf8.calss.php, map-файлами и модулем Encoding.php
(411.81 КБ) 714 скачиваний

Ответить

Вернуться в «Веб-картография»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя