CSS SVG динамически создавать цветные карты США

Я пытаюсь создать карту США с определенными штатами, окрашенными в определенные цвета для ссылок.

В настоящее время у меня есть код, который будет только цвета состояния одного цвета.
Мне нужны два цвета, поэтому сейчас мне нужно создать две карты.

Один из кодов для создания одной карты с одним цветовым кодом:

$bumperStates = array(
"tn", // Tennessee
"al", // Alabama
"ga", // Georgia
"ky", // Kentucky
"ca", // California
"nm", // New Mexico
"wy", // Wyoming
"ne", // Nebraska
"ks", // Kansas
"ok", // Oklahoma
"tx", // Texas
"ia", // Iowa
"mo", // Montana
"ar", // Arkansas
"la", // Louisiana
"ms", // Mississippi
"fl", // Florida
"nc", // North Carolina
"va", // Virginia
"wv", // West Virginia
"oh", // Ohio
"sd", // South Dakota
"in", // Indiana
"ky", // Kentucky
"sc", // South Carolina
"pa", // Pennsylvania
"ny", // New York
"vt", // Vermont
"me", // Maine
"il", // Illinois
"de", // Delaware
"nj", // New Jersey
"nh", // New Hampshire
"ri" // Rhode Island
);
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );

function createPNG( $svgfile, $pngfile ) {
$command = "rsvg " . $svgfile . " " . $pngfile;
$make_map = system( $command, $retval );
if ( $retval ) echo "PNG creation failed."; // Did it work?
}

$bumperstateArray = array();
// Add dot in front of each state to make it a CSS class selector
foreach ( $bumperStates as $bumperstate ) {
$bumperstateArray[] = '.' . $bumperstate;
}
// Make array into a string consisting of a list of states
$bumperstateList = implode( ', ', $bumperstateArray );

// Generate new map data
$map = file_get_contents( "USA-map.svg" );
if ( $bumperStates ) {
$newdata = preg_replace( '/\.bumperSign {/i', '.bumperSign, ' . $bumperstateList . ' {', $map );
}

// Write the new map to a file
/*
$fh = fopen( "newmap.svg", "w" );
fwrite( $fh, $newdata );
fclose( $fh );
*/

//createPNG( 'newmap.svg', 'newmap.png' );

// Output new SVG map
header( 'Content-type: image/svg+xml' );
print( $newdata );
flush();

А другой это:

$topstates = array(
"wa", // Washington
"ut", // Utag
"co", // Colorado
"mi", // Michigan
"id", // Idaho
"wy", // Wyoming
"ct", // Connecticut
"az", // Arizona
"or", // Oregon
"mt", // Montana
"nv", // Nevada
"nd", // North Dakota
"mn", // Minnessota
"wi", // Wisconsin
"md", // Maryland
"de", // Delaware
"ma" // Massechusetts

);
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );

function createPNG( $svgfile, $pngfile ) {
$command = "rsvg " . $svgfile . " " . $pngfile;
$make_map = system( $command, $retval );
if ( $retval ) echo "PNG creation failed."; // Did it work?
}

$topstateArray = array();
// Add dot in front of each state to make it a CSS class selector
foreach ( $topstates as $topstate ) {
$topstateArray[] = '.' . $topstate;
}
// Make array into a string consisting of a list of states
$topstateList = implode( ', ', $topstateArray );

// Generate new map data
$map = file_get_contents( "USA-map.svg" );
if ( $topstates ) {
$newdata = preg_replace( '/\.topSign {/i', '.topSign, ' . $topstateList . ' {', $map );
}

// Write the new map to a file
/*
$fh = fopen( "newmap.svg", "w" );
fwrite( $fh, $newdata );
fclose( $fh );
*/

//createPNG( 'newmap.svg', 'newmap.png' );

// Output new SVG map
header( 'Content-type: image/svg+xml' );
print( $newdata );
flush();

И когда я попытался объединить два, я придумал:

$bumperStates = array(
"tn", // Tennessee
"al", // Alabama
"ga", // Georgia
"ky", // Kentucky
"ca", // California
"nm", // New Mexico
"wy", // Wyoming
"ne", // Nebraska
"ks", // Kansas
"ok", // Oklahoma
"tx", // Texas
"ia", // Iowa
"mo", // Montana
"ar", // Arkansas
"la", // Louisiana
"ms", // Mississippi
"fl", // Florida
"nc", // North Carolina
"va", // Virginia
"wv", // West Virginia
"oh", // Ohio
"sd", // South Dakota
"in", // Indiana
"ky", // Kentucky
"sc", // South Carolina
"pa", // Pennsylvania
"ny", // New York
"vt", // Vermont
"me", // Maine
"il", // Illinois
"de", // Delaware
"nj", // New Jersey
"nh", // New Hampshire
"ri" // Rhode Island
);
$topStates = array(
"wa", // Washington
"ut", // Utag
"co", // Colorado
"mi", // Michigan
"id", // Idaho
"wy", // Wyoming
"ct", // Connecticut
"az", // Arizona
"or", // Oregon
"mt", // Montana
"nv", // Nevada
"nd", // North Dakota
"mn", // Minnessota
"wi", // Wisconsin
"md", // Maryland
"de", // Delaware
"ma" // Massechusetts

);
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );

function createPNG( $svgfile, $pngfile ) {
$command = "rsvg " . $svgfile . " " . $pngfile;
$make_map = system( $command, $retval );
if ( $retval ) echo "PNG creation failed."; // Did it work?
}

$bumperstateArray = array();
// Add dot in front of each state to make it a CSS class selector
foreach ( $bumperStates as $bumperstate ) {
$bumperstateArray[] = '.' . $bumperstate;
}
$topstateArray = array();
// Add dot in front of each state to make it a CSS class selector
foreach ( $topStates as $topstate ) {
$topstateArray[] = '.' . $topstate;
}
// Make array into a string consisting of a list of states
$bumperstateList = implode( ', ', $bumperstateArray );
$topstateList = implode( ', ', $topstateArray );

// Generate new map data
$map = file_get_contents( "USA-map.svg" );
if ( $bumperStates ) {
$newdata = preg_replace( '/\.bumperSign {/i', '.bumperSign, ' . $bumperstateList . ' {', $map );
}
if ( $topStates ) {
$newdata .= preg_replace( '/\.topSign {/i', '.topSign, ' . $topstateList . ' {', $map );
}

// Write the new map to a file
/*
$fh = fopen( "newmap.svg", "w" );
fwrite( $fh, $newdata );
fclose( $fh );
*/

//createPNG( 'newmap.svg', 'newmap.png' );

// Output new SVG map
header( 'Content-type: image/svg+xml' );
print( $newdata );
flush();

Половина карты генерирует, но затем я получаю следующую ошибку:

error on line 390 at column 12: XML declaration allowed only at the start of the document

Ошибка должна быть из файла SVG, так как это единственный файл, содержащий более 300 строк.

Я не могу опубликовать содержимое файла SVG, потому что он слишком длинный: / StackOverflow говорит Body is limited to 30000 characters; you entered 113909

Все оригинальные файлы находятся здесь: https://github.com/kaldari/SVG-map-maker

Может быть, кто-то может сказать мне, что я сделал что-то не так на стороне PHP?

1

Решение

Решение

Вам необходимо применить вторую замену к документу, который уже был обработан:

// Generate new map data (and assuming you want to keep $map intact)
$newdata = $map = file_get_contents( "USA-map.svg" );
if ( $bumperStates ) {
$newdata = preg_replace( '/\.bumperSign {/i', '.bumperSign, ' . $bumperstateList . ' {', $newdata  );
}
if ( $topStates ) {
$newdata = preg_replace( '/\.topSign {/i', '.topSign, ' . $topstateList . ' {', $newdata );
}

Объяснение

Ошибка довольно очевидна, вы пытаетесь повторно объявить XML-документ там, где он уже существует. Подробно:

  • Файл SVG по сути является файлом XML
  • Вы не можете объявить XML-документ дважды в одном и том же файле.
  • Вы добавляете файл SVG в другой файл SVG, что означает, что вы объявляете два XML-документа в одном файле

Вопрос здесь:

if ( $topStates ) {
$newdata .= preg_replace( '/\.topSign {/i', '.topSign, ' . $topstateList . ' {', $map );
}

Что в основном приводит к этому (и это не разрешено):

<?xml ...?><svg>...</svg><?xml ...?><svg>...</svg>
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]