Вилучення координат з файлу dxf autocad за допомогою функції explode php

Вилучення координат з файлу dxf autocad за допомогою функції explode php

Функція explode () досить проста, але надзвичайно корисна і використовується в кодуванні постійно. Якщо ця функція не застосовна, використовують формальні вирази, але вони працюють повільніше, тому вигідно працювати з готовими функціями php, щоб прискорити свою програму.

Explode php: опис роботи функції та її практичне застосування

Функція отримує на вхід рядок, розбиває його по ділнику і присвоює значення масиву з числовими ключами.

На прикладі dxf autocad спробуйте витягти координати та намалювати креслення за допомогою GD Library php.

Файл dxf - це звичайний текстовий документ, в якому записано координати всіх креслень. Виглядає він так:

ENTITIES - це сутності, LWPOLYLINE - замкнутий багатокутник, цифра 10 позначає координату x, після неї йде значення (тобто, x = 0.0), цифра 20 позначає y, її значення з наступного рядка (тобто, y = 500.0), нічого складного.

Знайдемо в файлі dxf необхідну нам інформацію. Для цього застосуємо функцію strchr (), яка знайде нам сутності (ENTITIES) і багатокутники (LWPOLYLINE):

$content = file_get_contents('stairs.dxf');
$entities = strchr($content, ""ENTITIES"");
$endsec = strchr($entities, ""ENDSEC"", true);
$entitie_string = $endsec;

Функція explode php допоможе виштовхнути координати. У цьому прикладі використовуємо тільки багатокутник, але в кресленнях багато й інших фігур, тому присвоїмо їх масиву. Ми розглядаємо тільки LWPOLYLINE:


$entities_array = array(""LWPOLYLINE"");

Наступний приклад знаходить позиції всіх LWPOLYLINE в текстовому документі dxf:

$lastPos = 0;
$positions_entities = array();
foreach($entities_array as $key_needle =>$entitie){
 while (($lastPos = strpos($entitie_string, $entitie, $lastPos))!== false) {
        $positions_entities[$lastPos] = $entitie;
        $lastPos = $lastPos + strlen($entitie);
 }
}
$array_keys_positions = array_keys($positions_entities);
$sizeof_array_positions = sizeof($array_keys_positions);
for($i=0; $i< $sizeof_array_positions; $i++){
    if(isset($array_keys_positions[$i+1])){
        $entities_string_array[$positions_entities[$array_keys_positions[$i]]][$array_keys_positions[$i]] = substr($entitie_string, $array_keys_positions[$i], $array_keys_positions[$i+1] - $array_keys_positions[$i] );
    }
    else{
        $entities_string_array[$positions_entities[$array_keys_positions[$i]]][$array_keys_positions[$i]] = substr($first_entitie_string, $array_keys_positions[$i] );
    }
}

Всі рядки багатокутників тепер знаходяться в масиві, тобто, у нас три багатокутники, а значить три ключі і три значення. У значеннях містяться рядки з інформацією з файлу dxf про ці багатокутники. Тепер необхідно розбити ці рядки, щоб виділити з них координати. Для цього використовуємо explode ():

foreach( $entities_string_array as $key_ent =>$value_ent){
 foreach( $value_ent as $key_val =>$value_e  ){
  $explode_value_e[$key_ent][$key_val] = explode(PHP_EOL,  $value_e);
 }
}

З отриманого багатовимірного масиву отримаємо значення, які слідують за позначками 10 (x) і 20 (y):

$lwpolyline_array = $explode_value_e[""LWPOLYLINE""];
$k = 0;
foreach( $lwpolyline_array as $lw_key => $explode_key ){
 foreach( $explode_key as $key => $lwpolyline_value){
  if( $lwpolyline_value == '10' ){
   $coordinates[$k][] = $coordinates_db[] = $coordinates_x[] = (float)$explode_key[$key+1];
  }else if( $lwpolyline_value == '20' ){
   $coordinates[$k][] = $coordinates_db[] = $coordinates_y[] = (float)$explode_key[$key+1];
  }
 }
 $implode_coordinates_db[$k] = implode(';',$coordinates_db);
 $k++;
}
$width = max($coordinates_x) - min($coordinates_x);
$height = max($coordinates_y) - min($coordinates_y);


Масив $ coordinates містить координати багатокутників, $ coordinates _ db використовуватимемо для запису значень х і y в базу даних, а $ coordinates _ x і $ coordinates _ y потрібні для визначення ширини і висоти нашого малюнка в бібліотеці GD php.

Об 'єднання даних у рядок за допомогою implode () для компактного зберігання інформації в MySQL

Для зберігання в базі даних зберемо координати в рядок за допомогою implode (), оскільки якщо зберігати кожну точку в окремій комірці, база даних поступово розростеться до величезних розмірів. Створювати таблицю в MySQL не будемо, щоб не ускладнювати код.

$implode_coordinates_db[$k] = implode(';',$coordinates_db);

Залишилося написати функцію, яка малюватиме картинку в GD Library:

$image_array = array($implode_coordinates_db, $width, $height);


Для створення зображення нам потрібні координати (використовуймо рядок з координатами, який можна витягти з бази даних $ implode _ coordinates _ db), ширина і висота.

Виклик функції:

$image_base64 = image_create($image_array);

І сама функція:

function image_create( $image_array ){
 $implode_coordinates = $image_array[0];
 $width = $image_array[1];
 $height = $image_array[2];
 $im = imagecreatetruecolor($width+1, $height+1);
 $white=imagecolorallocate($im,255,255,255);
 $black = imagecolorallocate($im, 0, 0, 0);
 imagefilledrectangle($im, 0, 0, $width, $height, $white);
 foreach( $implode_coordinates as $key =>$coordinates_string ){
  $coordinates[$key] = explode(';', $coordinates_string);
  $polygon_arrays_count[$key]=count($coordinates[$key])/2;
  imagepolygon($im, $coordinates[$key], $polygon_arrays_count[$key] , $black);
 }
 ob_start();
 imagepng($im);
 $buffer = ob_get_clean();
 //ob_end_clean();
 $img = base64_encode($buffer);
 imagedestroy($im);
 return $img;
}


Розбиття рядка, отриманого з MySQL за допомогою explode ()

Функція отримує рядкові координати з бази даних, потім рядок розбивається за допомогою explode php, після чого imagepolygon () малює нам багатокутники.

$coordinates[$key] = explode(';', $coordinates_string);
imagepolygon($im, $coordinates[$key], $polygon_arrays_count[$key] , $black);

Для цього прикладу картинка створена у форматі imagepng base64_encode, але ви можете зберегти картинку в jpg або png.

Тепер можна вивести картинку в браузер:

$image_array = array($implode_coordinates_db, $width, $height);
$image_base64 = image_create($image_array);
$image_src='data:image/png;base64,'.$image_base64;
echo ""<img src='"".$image_src.""'>"";


Background зображення виглядатиме так:

Якщо є можливість застосувати вбудовані функції замість формальних виразів, процес виконання програми буде займати трохи менше часу, тому завжди має сенс спочатку спробувати досягти поставленої мети за допомогою готових рішень у php.

Весь код:

$content = file_get_contents('stairs.dxf');
$entities = strchr($content, ""ENTITIES"");
$endsec = strchr($entities, ""ENDSEC"", true);
$entitie_string = $endsec;
$entities_array = array(""LWPOLYLINE"");
$lastPos = 0;
$positions_entities = array();
foreach($entities_array as $key_needle =>$entitie){
 while (($lastPos = strpos($entitie_string, $entitie, $lastPos))!== false) {
        $positions_entities[$lastPos] = $entitie;
        $lastPos = $lastPos + strlen($entitie);
 }
}
$array_keys_positions = array_keys($positions_entities);
$sizeof_array_positions = sizeof($array_keys_positions);
for($i=0; $i< $sizeof_array_positions; $i++){
    if(isset($array_keys_positions[$i+1])){
        $entities_string_array[$positions_entities[$array_keys_positions[$i]]][$array_keys_positions[$i]] = substr($entitie_string, $array_keys_positions[$i], $array_keys_positions[$i+1] - $array_keys_positions[$i] );
    }
    else{
        $entities_string_array[$positions_entities[$array_keys_positions[$i]]][$array_keys_positions[$i]] = substr($entitie_string, $array_keys_positions[$i] );
    }
}
 
foreach( $entities_string_array as $key_ent =>$value_ent){
 foreach( $value_ent as $key_val =>$value_e  ){
  $explode_value_e[$key_ent][$key_val] = explode(PHP_EOL,  $value_e);
 }
}
$lwpolyline_array = $explode_value_e[""LWPOLYLINE""];
$k = 0;
foreach( $lwpolyline_array as $lw_key => $explode_key ){
 foreach( $explode_key as $key => $lwpolyline_value){
  if( $lwpolyline_value == '10' ){
   $coordinates[$k][] = $coordinates_db[] = $coordinates_x[] = (float)$explode_key[$key+1];
  }else if( $lwpolyline_value == '20' ){
   $coordinates[$k][] = $coordinates_db[] = $coordinates_y[] = (float)$explode_key[$key+1];
  }
 }
 $implode_coordinates_db[$k] = implode(';',$coordinates_db);
 $k++;
}
$width = max($coordinates_x) - min($coordinates_x);
$height = max($coordinates_y) - min($coordinates_y);
function image_create( $image_array ){
 $implode_coordinates = $image_array[0];
 $width = $image_array[1];
 $height = $image_array[2];
 $im = imagecreatetruecolor($width+1, $height+1);
 $white=imagecolorallocate($im,255,255,255);
 $black = imagecolorallocate($im, 0, 0, 0);
 imagefilledrectangle($im, 0, 0, $width, $height, $white);
 foreach( $implode_coordinates as $key =>$coordinates_string ){
  $coordinates[$key] = explode(';', $coordinates_string);
  $polygon_arrays_count[$key]=count($coordinates[$key])/2;
  imagepolygon($im, $coordinates[$key], $polygon_arrays_count[$key] , $black);
 }
 ob_start();
 imagepng($im);
 $buffer = ob_get_clean();
 //ob_end_clean();
 $img = base64_encode($buffer);
 imagedestroy($im);
 return $img;
}
$image_array = array($implode_coordinates_db, $width, $height);
$image_base64 = image_create($image_array);
$image_src='data:image/png;base64,'.$image_base64;
echo ""<img src='"".$image_src.""'>"";