From: Mark Wells Date: Fri, 22 Apr 2016 20:36:13 +0000 (-0700) Subject: Import original source of Map-Splat 0.01 X-Git-Url: http://git.freeside.biz/gitweb/?a=commitdiff_plain;ds=sidebyside;h=0fa4cb99554008d229834423afa0550065e11028;p=Map-Splat.git Import original source of Map-Splat 0.01 --- 0fa4cb99554008d229834423afa0550065e11028 diff --git a/Changes b/Changes new file mode 100644 index 0000000..e050fbc --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for Map-Splat + +0.01 Date/time + First version, released on an unsuspecting world. + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..8ec4231 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,8 @@ +Changes +Splat.pm +Makefile.PL +MANIFEST This list of files +README +t/00-load.t +t/manifest.t +t/splat.t diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..aee9697 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,26 @@ +use 5.006; +use strict; +use warnings FATAL => 'all'; +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'Map::Splat', + AUTHOR => q{Mark Wells }, + VERSION_FROM => 'Splat.pm', + ABSTRACT_FROM => 'Splat.pm', + LICENSE => 'Artistic_2_0', + PL_FILES => {}, + MIN_PERL_VERSION => 5.006, + CONFIGURE_REQUIRES => { + 'ExtUtils::MakeMaker' => 0, + }, + BUILD_REQUIRES => { + 'Test::More' => 0, + }, + PREREQ_PM => { + 'XML::LibXML' => 2, + 'Image::Magick' => 0, + }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'Map-Splat-*' }, +); diff --git a/Makefile.old b/Makefile.old new file mode 100644 index 0000000..d8927e7 --- /dev/null +++ b/Makefile.old @@ -0,0 +1,856 @@ +# This Makefile is for the Map::Splat extension to perl. +# +# It was generated automatically by MakeMaker version +# 7.0401 (Revision: 70401) from the contents of +# Makefile.PL. Don't edit this file, edit Makefile.PL instead. +# +# ANY CHANGES MADE HERE WILL BE LOST! +# +# MakeMaker ARGV: () +# + +# MakeMaker Parameters: + +# ABSTRACT_FROM => q[Splat.pm] +# AUTHOR => [q[Mark Wells ]] +# BUILD_REQUIRES => { Test::More=>q[0] } +# CONFIGURE_REQUIRES => { ExtUtils::MakeMaker=>q[0] } +# LICENSE => q[Artistic_2_0] +# MIN_PERL_VERSION => q[5.006] +# NAME => q[Map::Splat] +# PL_FILES => { } +# PREREQ_PM => { Test::More=>q[0] } +# TEST_REQUIRES => { } +# VERSION_FROM => q[Splat.pm] +# clean => { FILES=>q[Map-Splat-*] } +# dist => { COMPRESS=>q[gzip -9f], SUFFIX=>q[gz] } + +# --- MakeMaker post_initialize section: + + +# --- MakeMaker const_config section: + +# These definitions are from config.sh (via /usr/lib/x86_64-linux-gnu/perl/5.22/Config.pm). +# They may have been overridden via Makefile.PL or on the command line. +AR = ar +CC = x86_64-linux-gnu-gcc +CCCDLFLAGS = -fPIC +CCDLFLAGS = -Wl,-E +DLEXT = so +DLSRC = dl_dlopen.xs +EXE_EXT = +FULL_AR = /usr/bin/ar +LD = x86_64-linux-gnu-gcc +LDDLFLAGS = -shared -L/usr/local/lib -fstack-protector-strong +LDFLAGS = -fstack-protector-strong -L/usr/local/lib +LIBC = libc-2.21.so +LIB_EXT = .a +OBJ_EXT = .o +OSNAME = linux +OSVERS = 3.16.0 +RANLIB = : +SITELIBEXP = /usr/local/share/perl/5.22.1 +SITEARCHEXP = /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 +SO = so +VENDORARCHEXP = /usr/lib/x86_64-linux-gnu/perl5/5.22 +VENDORLIBEXP = /usr/share/perl5 + + +# --- MakeMaker constants section: +AR_STATIC_ARGS = cr +DIRFILESEP = / +DFSEP = $(DIRFILESEP) +NAME = Map::Splat +NAME_SYM = Map_Splat +VERSION = 0.01 +VERSION_MACRO = VERSION +VERSION_SYM = 0_01 +DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\" +XS_VERSION = 0.01 +XS_VERSION_MACRO = XS_VERSION +XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\" +INST_ARCHLIB = blib/arch +INST_SCRIPT = blib/script +INST_BIN = blib/bin +INST_LIB = blib/lib +INST_MAN1DIR = blib/man1 +INST_MAN3DIR = blib/man3 +MAN1EXT = 1p +MAN3EXT = 3pm +INSTALLDIRS = site +DESTDIR = +PREFIX = $(SITEPREFIX) +PERLPREFIX = /usr +SITEPREFIX = /usr/local +VENDORPREFIX = /usr +INSTALLPRIVLIB = /usr/share/perl/5.22 +DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB) +INSTALLSITELIB = /usr/local/share/perl/5.22.1 +DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB) +INSTALLVENDORLIB = /usr/share/perl5 +DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB) +INSTALLARCHLIB = /usr/lib/x86_64-linux-gnu/perl/5.22 +DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB) +INSTALLSITEARCH = /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 +DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH) +INSTALLVENDORARCH = /usr/lib/x86_64-linux-gnu/perl5/5.22 +DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH) +INSTALLBIN = /usr/bin +DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN) +INSTALLSITEBIN = /usr/local/bin +DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN) +INSTALLVENDORBIN = /usr/bin +DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN) +INSTALLSCRIPT = /usr/bin +DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT) +INSTALLSITESCRIPT = /usr/local/bin +DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT) +INSTALLVENDORSCRIPT = /usr/bin +DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT) +INSTALLMAN1DIR = /usr/share/man/man1 +DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR) +INSTALLSITEMAN1DIR = /usr/local/man/man1 +DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR) +INSTALLVENDORMAN1DIR = /usr/share/man/man1 +DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR) +INSTALLMAN3DIR = /usr/share/man/man3 +DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR) +INSTALLSITEMAN3DIR = /usr/local/man/man3 +DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR) +INSTALLVENDORMAN3DIR = /usr/share/man/man3 +DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR) +PERL_LIB = /usr/share/perl/5.22 +PERL_ARCHLIB = /usr/lib/x86_64-linux-gnu/perl/5.22 +PERL_ARCHLIBDEP = /usr/lib/x86_64-linux-gnu/perl/5.22 +LIBPERL_A = libperl.a +FIRST_MAKEFILE = Makefile +MAKEFILE_OLD = Makefile.old +MAKE_APERL_FILE = Makefile.aperl +PERLMAINCC = $(CC) +PERL_INC = /usr/lib/x86_64-linux-gnu/perl/5.22/CORE +PERL_INCDEP = /usr/lib/x86_64-linux-gnu/perl/5.22/CORE +PERL = "/usr/bin/perl" +FULLPERL = "/usr/bin/perl" +ABSPERL = $(PERL) +PERLRUN = $(PERL) +FULLPERLRUN = $(FULLPERL) +ABSPERLRUN = $(ABSPERL) +PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +PERL_CORE = 0 +PERM_DIR = 755 +PERM_RW = 644 +PERM_RWX = 755 + +MAKEMAKER = /usr/share/perl/5.22/ExtUtils/MakeMaker.pm +MM_VERSION = 7.0401 +MM_REVISION = 70401 + +# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). +# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) +# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) +# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. +MAKE = make +FULLEXT = Map/Splat +BASEEXT = Splat +PARENT_NAME = Map +DLBASE = $(BASEEXT) +VERSION_FROM = Splat.pm +OBJECT = +LDFROM = $(OBJECT) +LINKTYPE = dynamic +BOOTDEP = + +# Handy lists of source code files: +XS_FILES = +C_FILES = +O_FILES = +H_FILES = +MAN1PODS = +MAN3PODS = Splat.pm + +# Where is the Config information that we are using/depend on +CONFIGDEP = $(PERL_ARCHLIBDEP)$(DFSEP)Config.pm $(PERL_INCDEP)$(DFSEP)config.h + +# Where to build things +INST_LIBDIR = $(INST_LIB)/Map +INST_ARCHLIBDIR = $(INST_ARCHLIB)/Map + +INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT) +INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT) + +INST_STATIC = +INST_DYNAMIC = +INST_BOOT = + +# Extra linker info +EXPORT_LIST = +PERL_ARCHIVE = +PERL_ARCHIVEDEP = +PERL_ARCHIVE_AFTER = + + +TO_INST_PM = Splat.pm + +PM_TO_BLIB = Splat.pm \ + $(INST_LIB)/Map/Splat.pm + + +# --- MakeMaker platform_constants section: +MM_Unix_VERSION = 7.0401 +PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc + + +# --- MakeMaker tool_autosplit section: +# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto +AUTOSPLITFILE = $(ABSPERLRUN) -e 'use AutoSplit; autosplit($$$$ARGV[0], $$$$ARGV[1], 0, 1, 1)' -- + + + +# --- MakeMaker tool_xsubpp section: + + +# --- MakeMaker tools_other section: +SHELL = /bin/sh +CHMOD = chmod +CP = cp +MV = mv +NOOP = $(TRUE) +NOECHO = @ +RM_F = rm -f +RM_RF = rm -rf +TEST_F = test -f +TOUCH = touch +UMASK_NULL = umask 0 +DEV_NULL = > /dev/null 2>&1 +MKPATH = $(ABSPERLRUN) -MExtUtils::Command -e 'mkpath' -- +EQUALIZE_TIMESTAMP = $(ABSPERLRUN) -MExtUtils::Command -e 'eqtime' -- +FALSE = false +TRUE = true +ECHO = echo +ECHO_N = echo -n +UNINST = 0 +VERBINST = 0 +MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install([ from_to => {@ARGV}, verbose => '\''$(VERBINST)'\'', uninstall_shadows => '\''$(UNINST)'\'', dir_mode => '\''$(PERM_DIR)'\'' ]);' -- +DOC_INSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'perllocal_install' -- +UNINSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'uninstall' -- +WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'warn_if_old_packlist' -- +MACROSTART = +MACROEND = +USEMAKEFILE = -f +FIXIN = $(ABSPERLRUN) -MExtUtils::MY -e 'MY->fixin(shift)' -- +CP_NONEMPTY = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'cp_nonempty' -- + + +# --- MakeMaker makemakerdflt section: +makemakerdflt : all + $(NOECHO) $(NOOP) + + +# --- MakeMaker dist section: +TAR = tar +TARFLAGS = cvf +ZIP = zip +ZIPFLAGS = -r +COMPRESS = gzip -9f +SUFFIX = .gz +SHAR = shar +PREOP = $(NOECHO) $(NOOP) +POSTOP = $(NOECHO) $(NOOP) +TO_UNIX = $(NOECHO) $(NOOP) +CI = ci -u +RCS_LABEL = rcs -Nv$(VERSION_SYM): -q +DIST_CP = best +DIST_DEFAULT = tardist +DISTNAME = Map-Splat +DISTVNAME = Map-Splat-0.01 + + +# --- MakeMaker macro section: + + +# --- MakeMaker depend section: + + +# --- MakeMaker cflags section: + + +# --- MakeMaker const_loadlibs section: + + +# --- MakeMaker const_cccmd section: + + +# --- MakeMaker post_constants section: + + +# --- MakeMaker pasthru section: + +PASTHRU = LIBPERL_A="$(LIBPERL_A)"\ + LINKTYPE="$(LINKTYPE)"\ + LD="$(LD)"\ + PREFIX="$(PREFIX)" + + +# --- MakeMaker special_targets section: +.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT) + +.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir + + + +# --- MakeMaker c_o section: + + +# --- MakeMaker xs_c section: + + +# --- MakeMaker xs_o section: + + +# --- MakeMaker top_targets section: +all :: pure_all manifypods + $(NOECHO) $(NOOP) + + +pure_all :: config pm_to_blib subdirs linkext + $(NOECHO) $(NOOP) + +subdirs :: $(MYEXTLIB) + $(NOECHO) $(NOOP) + +config :: $(FIRST_MAKEFILE) blibdirs + $(NOECHO) $(NOOP) + +help : + perldoc ExtUtils::MakeMaker + + +# --- MakeMaker blibdirs section: +blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists + $(NOECHO) $(NOOP) + +# Backwards compat with 6.18 through 6.25 +blibdirs.ts : blibdirs + $(NOECHO) $(NOOP) + +$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_LIBDIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_LIBDIR) + $(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists + +$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_ARCHLIB) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHLIB) + $(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists + +$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_AUTODIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_AUTODIR) + $(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists + +$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHAUTODIR) + $(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists + +$(INST_BIN)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_BIN) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_BIN) + $(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists + +$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_SCRIPT) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_SCRIPT) + $(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists + +$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_MAN1DIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN1DIR) + $(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists + +$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_MAN3DIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN3DIR) + $(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists + + + +# --- MakeMaker linkext section: + +linkext :: $(LINKTYPE) + $(NOECHO) $(NOOP) + + +# --- MakeMaker dlsyms section: + + +# --- MakeMaker dynamic_bs section: + +BOOTSTRAP = + + +# --- MakeMaker dynamic section: + +dynamic :: $(FIRST_MAKEFILE) $(BOOTSTRAP) $(INST_DYNAMIC) + $(NOECHO) $(NOOP) + + +# --- MakeMaker dynamic_lib section: + + +# --- MakeMaker static section: + +## $(INST_PM) has been moved to the all: target. +## It remains here for awhile to allow for old usage: "make static" +static :: $(FIRST_MAKEFILE) $(INST_STATIC) + $(NOECHO) $(NOOP) + + +# --- MakeMaker static_lib section: + + +# --- MakeMaker manifypods section: + +POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--" +POD2MAN = $(POD2MAN_EXE) + + +manifypods : pure_all \ + Splat.pm + $(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) -u \ + Splat.pm $(INST_MAN3DIR)/Map::Splat.$(MAN3EXT) + + + + +# --- MakeMaker processPL section: + + +# --- MakeMaker installbin section: + + +# --- MakeMaker subdirs section: + +# none + +# --- MakeMaker clean_subdirs section: +clean_subdirs : + $(NOECHO) $(NOOP) + + +# --- MakeMaker clean section: + +# Delete temporary files but do not touch installed files. We don't delete +# the Makefile here so a later make realclean still has a makefile to use. + +clean :: clean_subdirs + - $(RM_F) \ + $(BASEEXT).bso $(BASEEXT).def \ + $(BASEEXT).exp $(BASEEXT).x \ + $(BOOTSTRAP) $(INST_ARCHAUTODIR)/extralibs.all \ + $(INST_ARCHAUTODIR)/extralibs.ld $(MAKE_APERL_FILE) \ + *$(LIB_EXT) *$(OBJ_EXT) \ + *perl.core MYMETA.json \ + MYMETA.yml blibdirs.ts \ + core core.*perl.*.? \ + core.[0-9] core.[0-9][0-9] \ + core.[0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9] \ + core.[0-9][0-9][0-9][0-9][0-9] lib$(BASEEXT).def \ + mon.out perl \ + perl$(EXE_EXT) perl.exe \ + perlmain.c pm_to_blib \ + pm_to_blib.ts so_locations \ + tmon.out + - $(RM_RF) \ + Map-Splat-* blib + $(NOECHO) $(RM_F) $(MAKEFILE_OLD) + - $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL) + + +# --- MakeMaker realclean_subdirs section: +realclean_subdirs : + $(NOECHO) $(NOOP) + + +# --- MakeMaker realclean section: +# Delete temporary files (via clean) and also delete dist files +realclean purge :: clean realclean_subdirs + - $(RM_F) \ + $(FIRST_MAKEFILE) $(MAKEFILE_OLD) + - $(RM_RF) \ + $(DISTVNAME) + + +# --- MakeMaker metafile section: +metafile : create_distdir + $(NOECHO) $(ECHO) Generating META.yml + $(NOECHO) $(ECHO) '---' > META_new.yml + $(NOECHO) $(ECHO) 'abstract: '\''Wrapper for the Splat! RF propagation modeling tool'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'author:' >> META_new.yml + $(NOECHO) $(ECHO) ' - '\''Mark Wells '\''' >> META_new.yml + $(NOECHO) $(ECHO) 'build_requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' Test::More: '\''0'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'configure_requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: '\''0'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'dynamic_config: 1' >> META_new.yml + $(NOECHO) $(ECHO) 'generated_by: '\''ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150005'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'license: unknown' >> META_new.yml + $(NOECHO) $(ECHO) 'meta-spec:' >> META_new.yml + $(NOECHO) $(ECHO) ' url: http://module-build.sourceforge.net/META-spec-v1.4.html' >> META_new.yml + $(NOECHO) $(ECHO) ' version: '\''1.4'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'name: Map-Splat' >> META_new.yml + $(NOECHO) $(ECHO) 'no_index:' >> META_new.yml + $(NOECHO) $(ECHO) ' directory:' >> META_new.yml + $(NOECHO) $(ECHO) ' - t' >> META_new.yml + $(NOECHO) $(ECHO) ' - inc' >> META_new.yml + $(NOECHO) $(ECHO) 'requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' perl: '\''5.006'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'version: '\''0.01'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'x_serialization_backend: '\''CPAN::Meta::YAML version 0.012'\''' >> META_new.yml + -$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml + $(NOECHO) $(ECHO) Generating META.json + $(NOECHO) $(ECHO) '{' > META_new.json + $(NOECHO) $(ECHO) ' "abstract" : "Wrapper for the Splat! RF propagation modeling tool",' >> META_new.json + $(NOECHO) $(ECHO) ' "author" : [' >> META_new.json + $(NOECHO) $(ECHO) ' "Mark Wells "' >> META_new.json + $(NOECHO) $(ECHO) ' ],' >> META_new.json + $(NOECHO) $(ECHO) ' "dynamic_config" : 1,' >> META_new.json + $(NOECHO) $(ECHO) ' "generated_by" : "ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150005",' >> META_new.json + $(NOECHO) $(ECHO) ' "license" : [' >> META_new.json + $(NOECHO) $(ECHO) ' "unknown"' >> META_new.json + $(NOECHO) $(ECHO) ' ],' >> META_new.json + $(NOECHO) $(ECHO) ' "meta-spec" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",' >> META_new.json + $(NOECHO) $(ECHO) ' "version" : "2"' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "name" : "Map-Splat",' >> META_new.json + $(NOECHO) $(ECHO) ' "no_index" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "directory" : [' >> META_new.json + $(NOECHO) $(ECHO) ' "t",' >> META_new.json + $(NOECHO) $(ECHO) ' "inc"' >> META_new.json + $(NOECHO) $(ECHO) ' ]' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "prereqs" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "build" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "Test::More" : "0"' >> META_new.json + $(NOECHO) $(ECHO) ' }' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "configure" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "ExtUtils::MakeMaker" : "0"' >> META_new.json + $(NOECHO) $(ECHO) ' }' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "runtime" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "perl" : "5.006"' >> META_new.json + $(NOECHO) $(ECHO) ' }' >> META_new.json + $(NOECHO) $(ECHO) ' }' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "release_status" : "stable",' >> META_new.json + $(NOECHO) $(ECHO) ' "version" : "0.01",' >> META_new.json + $(NOECHO) $(ECHO) ' "x_serialization_backend" : "JSON::PP version 2.27300"' >> META_new.json + $(NOECHO) $(ECHO) '}' >> META_new.json + -$(NOECHO) $(MV) META_new.json $(DISTVNAME)/META.json + + +# --- MakeMaker signature section: +signature : + cpansign -s + + +# --- MakeMaker dist_basics section: +distclean :: realclean distcheck + $(NOECHO) $(NOOP) + +distcheck : + $(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck + +skipcheck : + $(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck + +manifest : + $(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest + +veryclean : realclean + $(RM_F) *~ */*~ *.orig */*.orig *.bak */*.bak *.old */*.old + + + +# --- MakeMaker dist_core section: + +dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE) + $(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \ + -e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';' -- + +tardist : $(DISTVNAME).tar$(SUFFIX) + $(NOECHO) $(NOOP) + +uutardist : $(DISTVNAME).tar$(SUFFIX) + uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu + $(NOECHO) $(ECHO) 'Created $(DISTVNAME).tar$(SUFFIX)_uu' + +$(DISTVNAME).tar$(SUFFIX) : distdir + $(PREOP) + $(TO_UNIX) + $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME) + $(RM_RF) $(DISTVNAME) + $(COMPRESS) $(DISTVNAME).tar + $(NOECHO) $(ECHO) 'Created $(DISTVNAME).tar$(SUFFIX)' + $(POSTOP) + +zipdist : $(DISTVNAME).zip + $(NOECHO) $(NOOP) + +$(DISTVNAME).zip : distdir + $(PREOP) + $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME) + $(RM_RF) $(DISTVNAME) + $(NOECHO) $(ECHO) 'Created $(DISTVNAME).zip' + $(POSTOP) + +shdist : distdir + $(PREOP) + $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar + $(RM_RF) $(DISTVNAME) + $(NOECHO) $(ECHO) 'Created $(DISTVNAME).shar' + $(POSTOP) + + +# --- MakeMaker distdir section: +create_distdir : + $(RM_RF) $(DISTVNAME) + $(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \ + -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');" + +distdir : create_distdir distmeta + $(NOECHO) $(NOOP) + + + +# --- MakeMaker dist_test section: +disttest : distdir + cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL + cd $(DISTVNAME) && $(MAKE) $(PASTHRU) + cd $(DISTVNAME) && $(MAKE) test $(PASTHRU) + + + +# --- MakeMaker dist_ci section: + +ci : + $(PERLRUN) "-MExtUtils::Manifest=maniread" \ + -e "@all = keys %{ maniread() };" \ + -e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \ + -e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});" + + +# --- MakeMaker distmeta section: +distmeta : create_distdir metafile + $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -e q{META.yml};' \ + -e 'eval { maniadd({q{META.yml} => q{Module YAML meta-data (added by MakeMaker)}}) }' \ + -e ' or print "Could not add META.yml to MANIFEST: $$$${'\''@'\''}\n"' -- + $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -f q{META.json};' \ + -e 'eval { maniadd({q{META.json} => q{Module JSON meta-data (added by MakeMaker)}}) }' \ + -e ' or print "Could not add META.json to MANIFEST: $$$${'\''@'\''}\n"' -- + + + +# --- MakeMaker distsignature section: +distsignature : create_distdir + $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) }' \ + -e ' or print "Could not add SIGNATURE to MANIFEST: $$$${'\''@'\''}\n"' -- + $(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE + cd $(DISTVNAME) && cpansign -s + + + +# --- MakeMaker install section: + +install :: pure_install doc_install + $(NOECHO) $(NOOP) + +install_perl :: pure_perl_install doc_perl_install + $(NOECHO) $(NOOP) + +install_site :: pure_site_install doc_site_install + $(NOECHO) $(NOOP) + +install_vendor :: pure_vendor_install doc_vendor_install + $(NOECHO) $(NOOP) + +pure_install :: pure_$(INSTALLDIRS)_install + $(NOECHO) $(NOOP) + +doc_install :: doc_$(INSTALLDIRS)_install + $(NOECHO) $(NOOP) + +pure__install : pure_site_install + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + +doc__install : doc_site_install + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + +pure_perl_install :: all + $(NOECHO) umask 022; $(MOD_INSTALL) \ + "$(INST_LIB)" "$(DESTINSTALLPRIVLIB)" \ + "$(INST_ARCHLIB)" "$(DESTINSTALLARCHLIB)" \ + "$(INST_BIN)" "$(DESTINSTALLBIN)" \ + "$(INST_SCRIPT)" "$(DESTINSTALLSCRIPT)" \ + "$(INST_MAN1DIR)" "$(DESTINSTALLMAN1DIR)" \ + "$(INST_MAN3DIR)" "$(DESTINSTALLMAN3DIR)" + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + "$(SITEARCHEXP)/auto/$(FULLEXT)" + + +pure_site_install :: all + $(NOECHO) umask 02; $(MOD_INSTALL) \ + read "$(SITEARCHEXP)/auto/$(FULLEXT)/.packlist" \ + write "$(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist" \ + "$(INST_LIB)" "$(DESTINSTALLSITELIB)" \ + "$(INST_ARCHLIB)" "$(DESTINSTALLSITEARCH)" \ + "$(INST_BIN)" "$(DESTINSTALLSITEBIN)" \ + "$(INST_SCRIPT)" "$(DESTINSTALLSITESCRIPT)" \ + "$(INST_MAN1DIR)" "$(DESTINSTALLSITEMAN1DIR)" \ + "$(INST_MAN3DIR)" "$(DESTINSTALLSITEMAN3DIR)" + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + "$(PERL_ARCHLIB)/auto/$(FULLEXT)" + +pure_vendor_install :: all + $(NOECHO) umask 022; $(MOD_INSTALL) \ + "$(INST_LIB)" "$(DESTINSTALLVENDORLIB)" \ + "$(INST_ARCHLIB)" "$(DESTINSTALLVENDORARCH)" \ + "$(INST_BIN)" "$(DESTINSTALLVENDORBIN)" \ + "$(INST_SCRIPT)" "$(DESTINSTALLVENDORSCRIPT)" \ + "$(INST_MAN1DIR)" "$(DESTINSTALLVENDORMAN1DIR)" \ + "$(INST_MAN3DIR)" "$(DESTINSTALLVENDORMAN3DIR)" + + +doc_perl_install :: all + +doc_site_install :: all + $(NOECHO) $(ECHO) Appending installation info to "$(DESTINSTALLSITEARCH)/perllocal.pod" + -$(NOECHO) umask 02; $(MKPATH) "$(DESTINSTALLSITEARCH)" + -$(NOECHO) umask 02; $(DOC_INSTALL) \ + "Module" "$(NAME)" \ + "installed into" $(INSTALLSITELIB) \ + LINKTYPE "$(LINKTYPE)" \ + VERSION "$(VERSION)" \ + EXE_FILES "$(EXE_FILES)" \ + >> "$(DESTINSTALLSITEARCH)/perllocal.pod" + +doc_vendor_install :: all + + +uninstall :: uninstall_from_$(INSTALLDIRS)dirs + $(NOECHO) $(NOOP) + +uninstall_from_perldirs :: + +uninstall_from_sitedirs :: + $(NOECHO) $(UNINSTALL) "$(SITEARCHEXP)/auto/$(FULLEXT)/.packlist" + +uninstall_from_vendordirs :: + + +# --- MakeMaker force section: +# Phony target to force checking subdirectories. +FORCE : + $(NOECHO) $(NOOP) + + +# --- MakeMaker perldepend section: + + +# --- MakeMaker makefile section: +# We take a very conservative approach here, but it's worth it. +# We move Makefile to Makefile.old here to avoid gnu make looping. +$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP) + $(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?" + $(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..." + -$(NOECHO) $(RM_F) $(MAKEFILE_OLD) + -$(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) + - $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL) + $(PERLRUN) Makefile.PL + $(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <==" + $(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command. <==" + $(FALSE) + + + +# --- MakeMaker staticmake section: + +# --- MakeMaker makeaperl section --- +MAP_TARGET = perl +FULLPERL = "/usr/bin/perl" + +$(MAP_TARGET) :: static $(MAKE_APERL_FILE) + $(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@ + +$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib + $(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET) + $(NOECHO) $(PERLRUNINST) \ + Makefile.PL DIR="" \ + MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ + MAKEAPERL=1 NORECURS=1 CCCDLFLAGS= + + +# --- MakeMaker test section: + +TEST_VERBOSE=0 +TEST_TYPE=test_$(LINKTYPE) +TEST_FILE = test.pl +TEST_FILES = t/*.t +TESTDB_SW = -d + +testdb :: testdb_$(LINKTYPE) + +test :: $(TEST_TYPE) subdirs-test + +subdirs-test :: + $(NOECHO) $(NOOP) + + +test_dynamic :: pure_all + PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES) + +testdb_dynamic :: pure_all + PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE) + +test_ : test_dynamic + +test_static :: test_dynamic +testdb_static :: testdb_dynamic + + +# --- MakeMaker ppd section: +# Creates a PPD (Perl Package Description) for a binary distribution. +ppd : + $(NOECHO) $(ECHO) '' > $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' Wrapper for the Splat! RF propagation modeling tool' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' Mark Wells <mark@freeside.biz>' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) '' >> $(DISTNAME).ppd + + +# --- MakeMaker pm_to_blib section: + +pm_to_blib : $(FIRST_MAKEFILE) $(TO_INST_PM) + $(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', q[$(PM_FILTER)], '\''$(PERM_DIR)'\'')' -- \ + Splat.pm $(INST_LIB)/Map/Splat.pm + $(NOECHO) $(TOUCH) pm_to_blib + + +# --- MakeMaker selfdocument section: + + +# --- MakeMaker postamble section: + + +# End. diff --git a/README b/README new file mode 100644 index 0000000..95ba4ba --- /dev/null +++ b/README @@ -0,0 +1,85 @@ +Map-Splat + +The README is used to introduce the module and provide instructions on +how to install the module, any machine dependencies it may have (for +example C compilers and installed libraries) and any other information +that should be provided before the module is installed. + +A README file is required for CPAN modules since CPAN extracts the README +file from a module distribution so that people browsing the archive +can use it to get an idea of the module's uses. It is usually a good idea +to provide version information here so that people can decide whether +fixes for the module are worth downloading. + + +INSTALLATION + +To install this module, run the following commands: + + perl Makefile.PL + make + make test + make install + +SUPPORT AND DOCUMENTATION + +After installing, you can find documentation for this module with the +perldoc command. + + perldoc Map::Splat + +You can also look for information at: + + RT, CPAN's request tracker (report bugs here) + http://rt.cpan.org/NoAuth/Bugs.html?Dist=Map-Splat + + AnnoCPAN, Annotated CPAN documentation + http://annocpan.org/dist/Map-Splat + + CPAN Ratings + http://cpanratings.perl.org/d/Map-Splat + + Search CPAN + http://search.cpan.org/dist/Map-Splat/ + + +LICENSE AND COPYRIGHT + +Copyright (C) 2016 Mark Wells + +This program is free software; you can redistribute it and/or modify it +under the terms of the the Artistic License (2.0). You may obtain a +copy of the full license at: + +L + +Any use, modification, and distribution of the Standard or Modified +Versions is governed by this Artistic License. By using, modifying or +distributing the Package, you accept this license. Do not use, modify, +or distribute the Package, if you do not accept this license. + +If your Modified Version has been derived from a Modified Version made +by someone other than you, you are nevertheless required to ensure that +your Modified Version complies with the requirements of this license. + +This license does not grant you the right to use any trademark, service +mark, tradename, or logo of the Copyright Holder. + +This license includes the non-exclusive, worldwide, free-of-charge +patent license to make, have made, use, offer to sell, sell, import and +otherwise transfer the Package with respect to any patent claims +licensable by the Copyright Holder that are necessarily infringed by the +Package. If you institute patent litigation (including a cross-claim or +counterclaim) against any party alleging that the Package constitutes +direct or contributory patent infringement, then this Artistic License +to you shall terminate on the date that such litigation is filed. + +Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER +AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. +THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY +YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR +CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR +CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/Splat.pm b/Splat.pm new file mode 100644 index 0000000..5729345 --- /dev/null +++ b/Splat.pm @@ -0,0 +1,521 @@ +package Map::Splat; + +use 5.006; +use strict; +use warnings FATAL => 'all'; + +use File::chdir; +use File::Temp qw(tempdir); +use File::Path qw(make_path); +use File::Slurp qw(read_file write_file); +use XML::LibXML::Simple qw(XMLin); +use List::Util qw(min max); +use Data::Dumper; +use Image::Magick; +use Moo; +use POSIX ('floor', 'ceil'); +use v5.10; + +=head1 NAME + +Map::Splat - Wrapper for the Splat! RF propagation modeling tool + +=head1 VERSION + +Version 0.01 + +=cut + +our $VERSION = '0.01'; + +=head1 SYNOPSIS + + use Map::Splat; + + my $foo = Map::Splat->new(); + ... + +=head1 METHODS + +=over 4 + +=cut + +# requires: +# - Splat +# - wget +# - zip +# - gdal-bin package (not used yet, but just wait) +# - XML::LibXML +# - ImageMagick + +my $SRTM_DIR = $ENV{HOME} . '/.splat'; +my $SRTM_PATH = 'http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America'; +my $SPLAT_CMD = '/usr/bin/splat'; + +=item new PARAMETERS + +Constructs a new mapping scenario. This takes the following parameters: + +lon: the tower longitude (east is positive) + +lat: the tower latitude (north is positive) + +height: the tower height above ground level, in feet + +freq: the frequency, in MHz + +h_width: the horizontal beamwidth, in degrees + +v_width: the vertical beamwidth, in degrees + +azimuth: the antenna orientation, in degrees from north (90 = east) + +tilt: the downward tilt of the antenna, in degrees + +and optionally accepts: + +dir: the working directory to use; defaults to a random tempdir + +id: the filename prefix for working files; defaults to '1' + +name: a string describing the tower; defaults to 'Tower' + +min_loss: the lowest path loss level to show on the map; defaults to 80 dB + +max_loss: the highest path loss level to show on the map; defaults to 160 dB + +=cut + +foreach ( qw( lon lat height freq h_width v_width azimuth tilt ) ) { + has $_ => ( is => 'rw', required => 1 ); +} + +has 'dir' => ( + is => 'ro', + default => sub { + tempdir(CLEANUP => 1) + }, +); + +has 'id' => ( + is => 'ro', + default => sub { 1 } +); + +has 'name' => ( + is => 'ro', + default => sub { 'Tower' } +); + +# there are more sophisticated ways to calculate this. for now we just expose +# the ends of the scale as optional parameters. +has 'min_loss' => ( + is => 'ro', + default => sub { 80 } +); + +has 'max_loss' => ( + is => 'ro', + default => sub { 160 } +); + +=item image + +After calling I this will contain an L object with +the raw image data. + +=cut + +has 'image' => ( + is => 'rw', +); + +=item box + +After calling I this will contain a hashref of 'north', 'south', +'east', and 'west' indicating the bounds of the map area. + +=cut + +has 'box' => ( + is => 'rw', + default => sub { +{} } +); + +=item db_colors + +Returns a hashref of (path loss level in dB) => (color level). + +=cut + +sub db_colors { + my $self = shift; + my %color; + # we have 32 color bands; find the width of a single band + my $db_step = ($self->max_loss - $self->min_loss) / 32; + for (my $i = 0; $i < 32; $i++) { + # + 1 here so that the highest band is _above_ the -db switch setting + my $db = ceil($self->max_loss - ($i * $db_step)) + 1; + my $color = 248 - ($i * 8); + $color{$db} = $color; + } + \%color; +} + +sub ew { + my $lon = shift; + $lon < 0 ? 'W' : 'E'; +} + +sub ns { + my $lat = shift; + $lat < 0 ? 'S' : 'N'; +} + +sub debug { + my $self = shift; + my $arg = shift; + if (ref $arg) { + warn Dumper($arg); + } else { + warn "$arg\n"; + } +} + +=item calculate + +Invoke Splat to create a map. Currently, the map will cover the 1-degree +quadrangle containing the tower location. + +=cut + +sub calculate { + my $self = shift; + + my $signed_lat = $self->lat; + my $signed_lon = $self->lon; + + my $id = $self->id; + + local $CWD = $self->dir; + + # write the site file + # note that Splat wants longitude in degrees west, from 0 to <360 + # (this will also matter for SDF files) + my $splat_lon = -1 * $signed_lon; + $splat_lon += 360 if $splat_lon < 0; + + $self->debug("creating QTH file"); + write_file("$id.qth", + $self->name . "\n" . + $signed_lat . "\n" . + $splat_lon . "\n" . + $self->height . "\n" + ); + + # Longley-Rice parameters + my $freq = $self->freq; + my $pol = 1; # polarization = vertical + $self->debug("creating LRP file for $freq MHz"); + + my $lrp = <debug("creating $id.lcf\n"); + my $lcf = ''; + my $colors = $self->db_colors; + for my $db (sort { $a <=> $b } keys %$colors) { + my $red = $colors->{$db}; + $lcf .= "$db: $red, 0, 0\n"; + } + write_file("$id.lcf", $lcf); + + # AZ file: radiation pattern in horizontal plane + # should be able to take this as an input (and kinda can, by overriding + # antenna_pattern) + my $bearing = $self->azimuth; + my $downtilt = $self->tilt; + my ($az, $el) = $self->antenna_pattern; + $self->debug("creating $id.az for bearing $bearing\n"); + + open my $fh, '>', "$id.az"; + printf $fh "%0.1f\n", ($bearing); + foreach my $t (sort { $a <=> $b } keys (%$az)) { + printf $fh "%d\t%0.6f\n", ($t, $az->{$t}); + } + + close $fh; + + # EL file: radiation pattern in vertical plane + $self->debug("creating $id.el for downtilt $downtilt\n"); + open $fh, '>', "$id.el"; + printf $fh "%0.1f\t%0.1f\n", ($downtilt, $bearing); + foreach my $t (sort { $a <=> $b } keys (%$el)) { + printf $fh "%0.1f\t%0.3f\n", ($t, $el->{$t}); + } + close $fh; + + # make sure we have SRTM for the area around the antenna + # ("area around the antenna" should be configurable) + # (and support SRTM1/high def version? only works in North America) + + for (my $dx = -2; $dx <= 2; $dx++) { + for (my $dy = -2; $dy <= 2; $dy++) { + my $splat_lon_east = floor($splat_lon) + $dx; + my $splat_lon_west = ($splat_lon_east + 1) % 360; + my $lat_south = floor($signed_lat) + $dy; + my $lat_north = $lat_south + 1; + + next if $lat_north > 90 or $lat_south < -90; # haha + + # the naming convention used by Splat's SDF files: + # south:north:east:west + # longitude is degrees west, from 0 to 359. + # note that the last one (from 1E to 0W) is 359:0, not 359:360 + my $sdffile = "$SRTM_DIR/$lat_south:$lat_north:$splat_lon_east:$splat_lon_west.sdf"; + if ( ! -f $sdffile ) { + if ( ! -d $SRTM_DIR ) { + make_path($SRTM_DIR); # dies on error + } + local $CWD = $SRTM_DIR; + # the USGS, though, just marks them as N/S and E/W. reference is the + # southwest corner. + # that's the negative of splat longitude, shifted to the range (-180, 180) + # or in the east, it's 360 - splat longitude + my $usgs_lon_west = -1 * $splat_lon_west; + $usgs_lon_west += 360 if $usgs_lon_west < -180; + my $hgtfile = ns($lat_south) . abs($lat_south) . + ew($usgs_lon_west) . abs($usgs_lon_west) . + '.hgt'; + my $zipfile = $hgtfile . '.zip'; + $self->debug("fetching $SRTM_PATH/$zipfile\n"); + my $status = system('wget', "$SRTM_PATH/$zipfile"); + if ( $status > 0 ) { + # normal if the tower location is near a coast, so try to continue + warn "couldn't download $zipfile\n"; + next; + } + $status = system('unzip', $zipfile); + # this isn't normal though + die "couldn't extract $zipfile\n" if $status > 0; + # unfortunately gives no useful output + $status = system('srtm2sdf', $hgtfile); + unlink $hgtfile; + unlink $zipfile; + } + if ( ! -f $sdffile ) { + $self->debug("$sdffile could not be downloaded.\n"); + next; + } + $self->debug("using file $sdffile\n"); + } # $dy + } # $dx + + $self->debug("running Splat...\n"); + my @args = ( + '-d', $SRTM_DIR, + '-t', "$id.qth", # transmitter site + '-o', "$id.ppm", # output file name + '-db', $self->max_loss, # power level range + '-L', '30', # assumed receiver antenna height - XXX should be config + '-R', '10', # maximum coverage radius - XXX should be config + '-ngs', # do not show terrain + '-kml', # generate a KML also + '-N', # suppress noise + '-erp', '0', # transmitter power (only showing relative path loss, so 0) + ); + $self->debug(join(" ", @args) . "\n"); + my $rv = system($SPLAT_CMD, @args); + if ( $rv != 0 ) { + $rv = $rv >> 8; + die "splat command failed ($rv): $!"; + } + + # results now in .kml referencing .ppm. + # pull the .kml apart to find the coordinates + my $kml = XMLin("$id.kml"); + my $latlon = $kml->{'Folder'}->{'GroundOverlay'}->{'LatLonBox'}; + $self->box($latlon); + my $image = Image::Magick->new; + $image->Read("$id.ppm"); + $self->image($image); + # there's a lot we could do with this (GDAL polygonize, etc.) but for + # now just hold onto the output. +} + +=item png + +Returns the rendered map, as a PNG. The path loss data will be in the red +channel, scaled according to the I mapping. + +=cut + +sub png { + my $self = shift; + my $image = $self->image or return; + my $png = $image->Clone; + $png->Set(magick => 'png'); + $png->Transparent('white'); + return $png->ImageToBlob; +} + +=item mask + +Returns the map as a PNG, with solid red in the areas where the path loss is +below I. The rest of the image will be transparent. + +=cut + +sub mask { + my $self = shift; + my $image = $self->image or return; + my $png = $image->Clone; + $png->Set(magick => 'png'); + $png->Threshold(threshold => 254, channel => 'Red'); + $png->Transparent('white'); + return $png->ImageToBlob; +} + +=item box_geometry + +Returns the map area box as a GeoJSON-style geometry object. + +=cut + +sub box_geometry { + my $self = shift; + my $box = $self->box; + { + type => 'Polygon', + coordinates => [ + [ $box->{west}, $box->{south} ], + [ $box->{east}, $box->{south} ], + [ $box->{east}, $box->{north} ], + [ $box->{west}, $box->{north} ], + [ $box->{west}, $box->{south} ], + ], + }; +} + +#internal method; you can subclass and override this to create a different +#antenna pattern. + +sub antenna_pattern { + + my $self = shift; + my $beamwidth = $self->h_width; + + my $falloff = 2; + + my %az = (); + my %el = (); + my $theta = 0; + while ($theta < 360) { + + if ($theta <= ($beamwidth / 2)) { + $az{$theta} = 1.0; + } elsif ($theta >= (360 - ($beamwidth / 2))) { + $az{$theta} = 1.0; + } elsif ($theta > ($beamwidth / 2) and $theta < 180) { + my $x = ($theta - ($beamwidth / 2)) / ($beamwidth / 2); + $az{$theta} = 1+(-($x*$falloff)**2); + $az{$theta} = ($az{$theta} > 0) ? $az{$theta} : 0.001000; + } elsif ($theta < (360 - ($beamwidth / 2)) and $theta > 180) { + my $x = ($theta - (360 - ($beamwidth / 2))) / ($beamwidth / 2); + $az{$theta} = 1+(-(-$x*$falloff)**2); + $az{$theta} = ($az{$theta} > 0) ? $az{$theta} : 0.001000; + } else { + $az{$theta} = 0.001000; + } + + $theta++; + + } + + $beamwidth = $self->v_width; + $theta = -10; + while ($theta <= 90) { + + if (abs($theta) <= ($beamwidth / 2)) { + $el{$theta} = 1.0; + } else { + my $x = (abs($theta) - ($beamwidth / 2)) / ($beamwidth / 2); + $el{$theta} = 1+(-($x*$falloff)**2); + $el{$theta} = ($el{$theta} > 0) ? $el{$theta} : 0.001000; + } + + $theta++; + } + +# while ($theta <= 90) { +# +# if ($theta >= -10 and $theta <= 90) { +# $el{$theta} = 1.0; +# } else { +# $el{$theta} = 0.0; +# } +# +# $theta += 0.5; +# +# } + + return({%az}, {%el}); + +} + +=back + +=head1 AUTHOR + +Mark Wells, C<< >> + +=head1 BUGS + +Currently only works in North America due to a hardcoded download path. + +The antenna radiation patterns are somewhat arbitrary at the moment. + +Please report any bugs or feature requests to C, +or through the web interface at +L. I will be +notified, and then you'll automatically be notified of progress on your bug +as I make changes. + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command. + + perldoc Map::Splat + +=head1 ACKNOWLEDGEMENTS + +John Magliacane (KD2BD) created Splat! and released it under the GNU GPL. + +This library is based in part on code by Kristian Hoffmann of Fire2Wire +Internet Services. + +=head1 LICENSE AND COPYRIGHT + +Copyright 2016 Mark Wells. + +This program is free software; you can redistribute it and/or modify it +under the terms of the the Artistic License (2.0). You may obtain a +copy of the full license at: + +L + +=cut + +1; diff --git a/ignore.txt b/ignore.txt new file mode 100644 index 0000000..4ce34b6 --- /dev/null +++ b/ignore.txt @@ -0,0 +1,18 @@ +Makefile +Makefile.old +Build +Build.bat +META.* +MYMETA.* +.build/ +_build/ +cover_db/ +blib/ +inc/ +.lwpcookies +.last_cover_stats +nytprof.out +pod2htm*.tmp +pm_to_blib +Map-Splat-* +Map-Splat-*.tar.gz diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..fa5caa5 --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,13 @@ +#!perl -T +use 5.006; +use strict; +use warnings FATAL => 'all'; +use Test::More; + +plan tests => 1; + +BEGIN { + use_ok( 'Map::Splat' ) || print "Bail out!\n"; +} + +diag( "Testing Map::Splat $Map::Splat::VERSION, Perl $], $^X" ); diff --git a/t/manifest.t b/t/manifest.t new file mode 100644 index 0000000..6ddfe36 --- /dev/null +++ b/t/manifest.t @@ -0,0 +1,15 @@ +#!perl -T +use 5.006; +use strict; +use warnings FATAL => 'all'; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +my $min_tcm = 0.9; +eval "use Test::CheckManifest $min_tcm"; +plan skip_all => "Test::CheckManifest $min_tcm required" if $@; + +ok_manifest(); diff --git a/t/splat.t b/t/splat.t new file mode 100644 index 0000000..53dcac2 --- /dev/null +++ b/t/splat.t @@ -0,0 +1,29 @@ +#!perl +use 5.006; +use strict; +use warnings FATAL => 'all'; +use Test::More; + +plan tests => 2; + +use Map::Splat; +my $map = Map::Splat->new( + lon => -122.279, + lat => 37.939, + height => 300, + freq => 2460, + azimuth => 200, + h_width => 180, + v_width => 20, + tilt => 2, + max_loss => 180, + min_loss => 30, +); +$map->calculate; +ok( defined $map->box, 'bounding box exists' ); +ok( defined $map->png, 'PNG generated' ); + +$map->image->Write('splat.png'); +use File::Slurp 'write_file'; +write_file 'mask.png', $map->mask; +