Newsgroup: it.comp.www.php
Titolo: Script topografico pronto da eseguire!

<?
/****
Non so a quanti di voi potra' servire: a me serviva, altrimenti non
lo facevo :-)
E' un esempio di come il PHP possa servire non solo per il Web, ma 
anche per svariati usi interni: questo script e' adattissimo per
l'intranet di uno studio tecnico, dove l'architetto usa un Mac,
l'ingegnere un Sun e il geometra un 486 con Windows 95...
L'input e' una lista di dati nel formato nomepunto, A, B
(proveniente per esempio da un foglio di calcolo); l'output e'
un'immagine PNG di anteprima oppure un testo DXF, da salvare od aprire
con un cad direttamente.
A e B possono essere le coordinate cartesiane X e Y del punto, oppure
le sue coordinate polari (angolo e distanza), con l'angolo espresso in
gradi centesimali orari, zero a ore 12 (o nord, o in alto), come si
usa di solito per i rilievi catastali.
Nel disegno risultante il nome di ogni punto viene scritto centrato a
nord del punto, ad una distanza pari a meta' dell'altezza testo; il
tutto viene poi circondato da un bordo, opzionale.
Testi, punti e bordo vengono messi su layer separati.
L'output l'ho provato con Qcad (visto che e' GPL), ma "dovrebbe"
funzionare anche con Autocad: fatemi sapere.
Per chi volesse fare qualcosa di piu' le monumentali specifiche DXF
sono su
http://www.autodesk.com/techpubs/autocad/dxf/dxf2000htm.zip
L'anteprima viene realizzata in PNG usando le librerie GD. Non ho
ritenuto opportuno perfezionarla ulteriormente, visto che e'
opzionale. Quindi, se l'origine delle vostre coordinate e' molto
distante dai punti, come di solito succede con i punti catastali che
sono riferiti a qualche vetta sperduta, otterrete un'immagine di
anteprima MOLTO grande: non spaventatevi.
ATTENZIONE: 
non ci sono controlli di sicurezza, quindi NON mettete questo script
su Internet cosi' com'e'.
BUG:
se con Mozilla 1.1 per Linux l'immagine di anteprima non viene 
visualizzata, e' sufficiente premere il bottone "indietro" e
quindi quello "avanti". Credo sia un bug di Mozilla.
PER PROVARE:
queste sequenze forniranno entrambe 4 punti ai 4 angoli dell'immagine
in coordinate polari:
A,50,10
B,150,10
C,250,10
D,350,10
in coordinate cartesiane:
A,10,10
B,10,-10
C,-10,-10
D,-10,10
DA FARE:
Potrebbe essere interessante ridefinire le coordinate del punto zero,
giusto per avere un'anteprima migliore.
Prima o poi lo faro'.
ciao
Marco
bernama - chiocciola - libero punto it
P.S.: salvate pure l'intero messaggio come nomefile.php, tanto
questo testo e' in un commento ;-)
Attenzione solo che non ci siano righe vuote dopo l'ultimo ?>
altrimenti l'anteprima PNG potrebbe non funzionare.
****/
error_reporting(E_ALL);
if (isset($_POST["BOTTONE"])) {
    $Lpunti = $_POST["layer_punti"];
    $Ltesti = $_POST["layer_testi"];
    $Lbordo = $_POST["layer_bordo"];
    $Htesto = $_POST["htesto"];
    $Dtesto = $Htesto * 0.5;
    $zoom = $_POST["Zoom"];
    $MinX = 
2147483647
;
    $MaxX = -$MinX;
    $MinY = $MinX;
    $MaxY = -$MinX;
    $ToRad = M_PI/200;
    $num = 0;
    $punti = explode ("\n", trim($_POST["lista"]));
    foreach ($punti as $p) {
        list ($punto[$num]["nome"], $A, $B) = explode (",", $p, 3);
        $A = trim($A);
        $B = trim($B);
        if ($_POST["coordinate"] == "cartesiane") {
	        $punto[$num]["X"] = $A;
	        $punto[$num]["Y"] = $B;
        } else {
              $radA = $A * $ToRad;
              $punto[$num]["X"] = $B * sin($radA);
              $punto[$num]["Y"] = $B * cos($radA);
        }
        if ($punto[$num]["X"] > $MaxX) $MaxX = $punto[$num]["X"];
        if ($punto[$num]["Y"] > $MaxY) $MaxY = $punto[$num]["Y"];
        if ($punto[$num]["X"] < $MinX) $MinX = $punto[$num]["X"];
        if ($punto[$num]["Y"] < $MinY) $MinY = $punto[$num]["Y"];
        $num++;
    }
    if ($_POST["formato"]=="anteprima") {
        $margine = 50;
        $DeltaX = abs ($MaxX - $MinX);
        $DeltaY = abs ($MaxY - $MinY);
        if ($MinX > 0) { 
            $LatoX = (int) ($MaxX * $zoom) + $margine;
            $ZeroX = $margine/2;
        } else {
            $LatoX = (int) ($DeltaX * $zoom) + $margine;
            $ZeroX = abs ($MinX * $zoom) + ($margine/2);
        }
        if ($MinY > 0) { 
            $LatoY = (int) ($MaxY * $zoom) + $margine;
            $ZeroY = $LatoY - $margine/2;
        } else {
            $LatoY = (int) ($DeltaY * $zoom) + $margine;
            $ZeroY = abs($LatoY - abs($MinY * $zoom)) - ($margine/2);
        }
        $im  = ImageCreate ($LatoX, $LatoY); 
        $bgc = ImageColorAllocate ($im, 225, 225, 225);
		$tc  = ImageColorAllocate ($im, 0, 0, 0);
        $rosso = ImageColorAllocate ($im, 255, 40, 40);
        ImageArc ($im, $ZeroX, $ZeroY, 16, 16, 0, 360, $rosso);
        ImageLine ($im, 0, $ZeroY, $LatoX, $ZeroY, $rosso);
        ImageLine ($im, $ZeroX, 0, $ZeroX, $LatoY, $rosso);
        foreach ($punto as $key=>$value) {
            $XVpunto = $ZeroX + ($punto[$key]["X"] * $zoom);
            $YVpunto = $ZeroY - ($punto[$key]["Y"] * $zoom);
            ImageSetPixel ($im, $XVpunto, $YVpunto, $tc);
            ImageArc ($im, 
                $XVpunto, $YVpunto, 
                $zoom * 1.25, $zoom * 1.25, 0, 360, $tc);
            ImageString ($im, 4, 
                $XVpunto - ($zoom/2), $YVpunto + ($zoom/2), 
                $punto[$key]["nome"], $tc
                );
        }
        header ("Content-type: image/png");
		ImagePng ($im);
		exit;
    } else {
    	header ("Content-type: " . $_POST["formato"]);
    	echo $_POST["formato"] ."  0\n";
    	echo "SECTION\n";
    	echo "  2\n";
    	echo "ENTITIES\n";
    	foreach ($punto as $key=>$value) {
			echo "  0\n";
			echo "POINT\n";
			echo "  8\n";
			echo "$Lpunti\n";
			echo " 10\n";
			echo trim($punto[$key]["X"]) . "\n";
			echo " 20\n";
			echo trim($punto[$key]["Y"]) . "\n";
			echo " 62\n";
			echo "0\n";
			echo "  0\n";
			echo "TEXT\n";
			echo "  8\n";
			echo "$Ltesti\n";
			echo " 10\n";
			echo trim($punto[$key]["X"]) . "\n";
			echo " 20\n";
			echo trim(($punto[$key]["Y"]) + $Dtesto) . "\n";
			echo " 40\n";
			echo "$Htesto\n";
			echo " 72\n";
			echo "1\n";
			echo "  1\n";
			echo $punto[$key]["nome"] . "\n";
    	}
    	if ($Lbordo > "") {
			$LatoX = $MaxX - $MinX;
			$LatoY = $MaxY - $MinY;
			$BordoX = $LatoX * 0.1;
			$BordoY = $LatoY * 0.1;
			echo "  0\n";
			echo "LINE\n";
			echo "  8\n";
			echo "$Lbordo\n";
			echo " 10\n";
			echo ($MinX - $BordoX) . "\n";
			echo " 20\n";
			echo ($MinY - $BordoY) . "\n";
			echo " 11\n";
			echo ($MaxX + $BordoX) . "\n";
			echo " 21\n";
			echo ($MinY - $BordoY) . "\n";
			echo " 62\n";
			echo "0\n";
			echo "  0\n";
			echo "LINE\n";
			echo "  8\n";
			echo "$Lbordo\n";
			echo " 10\n";
			echo ($MinX - $BordoX) . "\n";
			echo " 20\n";
			echo ($MaxY + $BordoY) . "\n";
			echo " 11\n";
			echo ($MaxX + $BordoX) . "\n";
			echo " 21\n";
			echo ($MaxY + $BordoY) . "\n";
			echo " 62\n";
			echo "0\n";
			echo "  0\n";
			echo "LINE\n";
			echo "  8\n";
			echo "$Lbordo\n";
			echo " 10\n";
			echo ($MinX - $BordoX) . "\n";
			echo " 20\n";
			echo ($MinY - $BordoY) . "\n";
			echo " 11\n";
			echo ($MinX - $BordoX) . "\n";
			echo " 21\n";
			echo ($MaxY + $BordoY) . "\n";
			echo " 62\n";
			echo "0\n";
			echo "  0\n";
			echo "LINE\n";
			echo "  8\n";
			echo "$Lbordo\n";
			echo " 10\n";
			echo ($MaxX + $BordoX) . "\n";
			echo " 20\n";
			echo ($MinY - $BordoY) . "\n";
			echo " 11\n";
			echo ($MaxX + $BordoX) . "\n";
			echo " 21\n";
			echo ($MaxY + $BordoY) . "\n";
			echo " 62\n";
			echo "0\n";
    	}
    }
} else {
echo "
<html><head>
<title>Punti in DXF</title>
</head>
<body>
<h3>Conversione di coordinate da<br>
testo in formato &lt;nome punto&gt, &lt;X&gt;, &lt;Y&gt; o<br>
testo in formato &lt;nome punto&gt, &lt;angolo&gt;, &lt;distanza&gt;
o<br>
a DXF</h3>
<form action=\"$PHP_SELF\" method=post>
Nome layer punti: <input name=\"layer_punti\" value=\"Layer_Punti\">
<br><br>
Nome layer testi: <input name=\"layer_testi\" value=\"Layer_Testi\">
<br><br>
Nome layer bordo: <input name=\"layer_bordo\" value=\"Layer_Bordo\">
(vuoto per nessun bordo)<br><br>
Altezza testo: <input name=\"htesto\" value=1><br><br>
Elenco punti:<br>
<textarea name=\"lista\" cols=40 rows=12></textarea><br><br>
Coordinate:<br>
<input type=radio name=\"coordinate\" value=\"polari\" checked> polari
(angoli centesimali orari, 0&deg; a nord)<br>
<input type=radio name=\"coordinate\" value=\"cartesiane\"> cartesiane
<br><br>
Formato:<br>
<input type=radio name=\"formato\" value=\"text/plain\"> DXF come
 testo<br>
<input type=radio name=\"formato\" value=\"image/vnd.dxf\"> DXF come 
 immagine<br>
<input type=radio name=\"formato\" value=\"anteprima\" checked>
 Anteprima PNG
(zoom <input name=\"Zoom\" value=10 size=5>)<br>
<br>
<input type=submit value=\"OK\" name=\"BOTTONE\">
</form></body></html>
";
}
?>

 l'ingegnere un Sun e il geometra un 486 con Windows 95...
Non mi servirą mai a nulla, non mi interesso di topografia, non frequento
studi tecnici, le coordinate polari mi stanno pure sulle palle...
ma ti ringrazio per aver condiviso il tuo lavoro!!! É lo spirito giusto =)
Ludovico Grossi

l'ingegnere un Sun e il geometra un 486 con Windows 95...
Ho conosciuto ingegneri che usavano il DOS su 486
e geometri che usavano Linux su P4. Come la mettiamo?