Here at Conveyal, we work with US Census data a lot. Historically, retrieving this data has been a bit difficult, as you have to get the block level geometries from one place, data on demographics from another, and data on employment from a third. You then have to extract all the files and join them in GIS. It's even more complicated if you hail from an urban area that encompasses multiple states (like the home of Conveyal: Washington, DC). Finally, you have to interpret the column codes to map them to something meaningful for analysis (who knew that CNS05
meant "number of jobs in manufacturing", for example?)
How do we streamline this process so that we are not repeating the pre-processing everytime?
To solve this problem, we decided to create a seamless data source for US Census data. We retrieved the 11 million block-level geometries for all US states and territories, as well as LODES data for states where it is available. We merged all of these state-level datasets into a single national file, and then split it up into 63,645 Web Mercator tiles at zoom 11, stored on S3 in GeoBuf format. Each tile includes all blocks whose polygon overlaps that tile. We use our seamless-census tool to perform this processing step. We also gave all those cryptic columns human-readable names; since we're not using shapefiles, column names are not limited to ten characters. Below is a small snippet of the tiles we've rendered for the Washington D.C. metro area.
Once we've done that, it's relatively easy to extract data for an arbitrary geographic bounding box (even one that crosses state lines). We just select the tiles that overlap the area of interest, download them, and then run the features through a final geographic filter to weed out any overselection. Once we've done that, we can dump the features to a new GeoBuf file. We also wrote a tool to do that, which is also in the GitHub repository. It's also possible to perform extracts programatically from Java using our library, and it wouldn't be hard to implement the extractor in another language besides Java. Below we show the same region filtered through job density.
There's no reason why we should keep this to ourselves, either. This is open data and it should be accessible to the world, so we've gone ahead and made the S3 bucket (lodes-data
) where we store the tiles public. It's a requester-pays bucket, so anyone using it pays the (miniscule) S3 bandwidth costs directly to Amazon. Just use the credentials from your AWS account to access it; the bandwidth you use will be added to your AWS bill. The data are the 2015 TIGER/Line blocks for every state, and 2013 LODES data for all segments and job types. Massachusetts, Puerto Rico and the US Virgin Islands have no data available, and Kansas uses the 2011 data (rather than 2013) since newer data is not available. We haven't put demographic data from the decennial census in yet.
The format we've devised isn't specific to the US Census, either. We could use exactly the same infrastructure to handle extracts from any large dataset that can be represented as vector data, and then it could be accessed using the same tooling.
The extractor is also available as a Java class (see SeamlessSource and its subclasses in the seamless-census repository), so it's easy to integrate with programs written in Java. The extractor is fairly simple, so it shouldn't be difficult to port it to other languages where a geobuf library exists.
Import US Census data into a seamless storage environment. We have developed a python program to download both the TIGER and LODES datasets off U.S. Census servers. We also developed a Java package to download, load, store, and extract that TIGER and LODES data.
Here we create a python program that can pull the desired Census data from their servers resiliently. The first step we do is import the necessary packages for the program:
#!/usr/bin/python
from sys import argv
from urllib import urlretrieve
import zipfile
import os
import os.path
from shutil import copyfileobj
from time import sleep
We predefine a dictionary with the appropriate mapping of two character state abbreviations to State FIPS codes. Census uses FIPS codes to label the separate state level geography files which are not as human-readable.
fipsCodes = dict (
AK = "02", # ALASKA
AL = "01", # ALABAMA
AR = "05", # ARKANSAS
AS = "60", # AMERICAN SAMOA
AZ = "04", # ARIZONA
CA = "06", # CALIFORNIA
CO = "08", # COLORADO
CT = "09", # CONNECTICUT
DC = "11", # DISTRICT OF COLUMBIA
DE = "10", # DELAWARE
FL = "12", # FLORIDA
GA = "13", # GEORGIA
GU = "66", # GUAM
HI = "15", # HAWAII
IA = "19", # IOWA
ID = "16", # IDAHO
IL = "17", # ILLINOIS
IN = "18", # INDIANA
KS = "20", # KANSAS
KY = "21", # KENTUCKY
LA = "22", # LOUISIANA
MA = "25", # MASSACHUSETTS
MD = "24", # MARYLAND
ME = "23", # MAINE
MI = "26", # MICHIGAN
MN = "27", # MINNESOTA
MO = "29", # MISSOURI
MS = "28", # MISSISSIPPI
MT = "30", # MONTANA
NC = "37", # NORTH CAROLINA
ND = "38", # NORTH DAKOTA
NE = "31", # NEBRASKA
NH = "33", # NEW HAMPSHIRE
NJ = "34", # NEW JERSEY
NM = "35", # NEW MEXICO
NV = "32", # NEVADA
NY = "36", # NEW YORK
OH = "39", # OHIO
OK = "40", # OKLAHOMA
OR = "41", # OREGON
PA = "42", # PENNSYLVANIA
PR = "72", # PUERTO RICO
RI = "44", # RHODE ISLAND
SC = "45", # SOUTH CAROLINA
SD = "46", # SOUTH DAKOTA
TN = "47", # TENNESSEE
TX = "48", # TEXAS
UT = "49", # UTAH
VA = "51", # VIRGINIA
VI = "78", # VIRGIN ISLANDS
VT = "50", # VERMONT
WA = "53", # WASHINGTON
WI = "55", # WISCONSIN
WV = "54", # WEST VIRGINIA
WY = "56", # WYOMING
)
We now can parse our command-line arguments and create the filepaths we will store the appropriate files.
# parse arguments
outDir = argv[1]
states = [state.upper() for state in argv[2:]]
if len(states) == 1 and states[0] == 'ALL':
# download all states
print "Downloading all states"
states = fipsCodes.keys()
# check inputs
invalidStates = [state for state in states if not fipsCodes.has_key(state)]
if len(invalidStates) > 0:
print "Did not recognize states %s" % ' '.join(invalidStates)
# make the directory structure
os.makedirs(os.path.join(outDir, 'tiger'))
os.makedirs(os.path.join(outDir, 'jobs'))
os.makedirs(os.path.join(outDir, 'workforce'))
Now we can define our resilient download function and execute on every state abbreviation passed through the command line argument.
# Download the data we need for a particular [set of] states, or the entire country
# usage: downloadData.py outDir state_abbr [state_abbr . . .]
# Or use special code 'ALL'
# download resiliently
def retrieve(url, path):
for i in xrange(50):
try:
urlretrieve(url, path)
except:
print "error retrieving {0}, retrying".format(url)
sleep(5)
else:
break
# download the states
for state in states:
print 'processing %s' % state
print 'Downloading TIGER'
# get tiger
fips = fipsCodes[state]
zipout = os.path.join(outDir, "tiger", "{0}.zip".format(state))
retrieve("ftp://ftp2.census.gov/geo/tiger/TIGER2010/TABBLOCK/2010/tl_2010_{0}_tabblock10.zip".format(fips), zipout)
# unzip it
# adapted from http://stackoverflow.com/questions/12886768/
with zipfile.ZipFile(zipout) as zf:
for member in zf.infolist():
name = os.path.split(member.filename)[-1]
dest = os.path.join(outDir, 'tiger', name)
with zf.open(member) as stream:
with open(dest, 'w') as out:
copyfileobj(stream, out)
# we no longer need the zipfile
os.remove(zipout)
print 'Done with TIGER'
print 'Downloading LODES data'
# figure out the year of the latest available data
# Most states have 2013 data available
# see http://lehd.ces.census.gov/data/lodes/LODES7/LODESTechDoc7.1.pdf, page 2f
year = 2013
if state == 'KS':
year = 2011
elif state == 'MA' or state == 'PR' or state == 'VI':
print '{0} does not have LODES data available'.format(state)
year = 0
if year:
print "Dowloading {0} LODES data for {1}".format(year, state)
# get the rac file
out = os.path.join(outDir, 'workforce', '{0}_{1}_rac.csv.gz'.format(state, year))
retrieve("http://lehd.ces.census.gov/data/lodes/LODES7/{0}/rac/{0}_rac_S000_JT00_{1}.csv.gz".format(state.lower(), year), out)
# get the wac file
out = os.path.join(outDir, 'jobs', '{0}_{1}_wac.csv.gz'.format(state, year))
retrieve("http://lehd.ces.census.gov/data/lodes/LODES7/{0}/wac/{0}_wac_S000_JT00_{1}.csv.gz".format(state.lower(), year), out)
print 'Done with {0}'.format(state)
You can use the following program to download data from the Census bureau. Create a temporary directory to receive the files before you combine them and load them to S3, in a location that has plenty of disk space. The arguments are the temporary directory and the two-letter postal abbreviations of the states for which you want to retrieve data (you can also use the special code ALL to retrieve data for every state, territory and district). The command below, for instance, would download data for the greater Washington, DC megalopolis.
python downloadData.py temporary_dir DC MD VA WV DE
To begin loading the data we've just downloaded, we first have to create a Geobuf class. This is generated from Mapbox's Geobuf format and can be found here. Next we need to define a class to tile and store our Geobuf eventual Geobuf files, either locally or on S3.
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.conveyal.data.geobuf.GeobufEncoder;
import com.conveyal.data.geobuf.GeobufFeature;
import com.vividsolutions.jts.geom.Envelope;
import org.mapdb.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.NavigableSet;
import java.util.concurrent.*;
import java.util.function.BiFunction;
import java.util.zip.GZIPOutputStream;
/**
* Store geographic data by ID, with index by zoom-11 tile.
*/
public class ShapeDataStore {
public static final int ZOOM_LEVEL = 11;
private static final Logger LOG = LoggerFactory.getLogger(ShapeDataStore.class);
/** number of decimal places of precision to store */
public static final int PRECISION = 12;
private DB db;
/**
* set of Object[] { int[] { x, y }, Feature } for features at zoom 11
*/
private NavigableSet
Once that is done, we define a class that reads TIGER/Line data and converts to the Geobuf format.
import com.conveyal.data.geobuf.GeobufFeature;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.Query;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.referencing.CRS;
import java.io.File;
import java.util.HashMap;
/**
* Reads TIGER/Line data into a MapDB.
*/
public class TigerLineSource {
private File shapefile;
public TigerLineSource (File shapefile) {
this.shapefile = shapefile;
}
public void load (ShapeDataStore store) throws Exception {
FileDataStore fds = FileDataStoreFinder.getDataStore(shapefile);
SimpleFeatureSource src = fds.getFeatureSource();
Query q = new Query();
q.setCoordinateSystem(src.getInfo().getCRS());
q.setCoordinateSystemReproject(CRS.decode("EPSG:4326", true));
SimpleFeatureCollection sfc = src.getFeatures(q);
for (SimpleFeatureIterator it = sfc.features(); it.hasNext();) {
GeobufFeature feat = new GeobufFeature(it.next());
feat.id = null;
feat.numericId = Long.parseLong((String) feat.properties.get("GEOID10"));
feat.properties = new HashMap<>();
store.add(feat);
}
}
}
Now we define a class that converts the LODES data column names into more human-readable headers. This is done through a direct mapping we have done before hand.
import com.conveyal.data.geobuf.GeobufFeature;
import com.csvreader.CsvReader;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
/**
* Data source for LODES data.
*/
public class LodesSource {
private File input;
private LodesType type;
public LodesSource(File input, LodesType type) {
this.input = input;
this.type = type;
}
public void load(ShapeDataStore store) throws Exception {
InputStream csv = new GZIPInputStream(new BufferedInputStream(new FileInputStream(input)));
CsvReader reader = new CsvReader(new InputStreamReader(csv));
// rename the columns to something useful
//http://lehd.ces.census.gov/data/lodes/LODES7/LODESTechDoc7.1.pdf#page=7&zoom=auto,-266,580
Map colNames = new HashMap<>();
colNames.put("C000", "total");
colNames.put("CA01", "age 29 or younger");
colNames.put("CA02", "age 30 to 54");
colNames.put("CA03", "age 55 or older");
colNames.put("CE01", "with earnings $1250 per month or less");
colNames.put("CE02", "with earnings $1251 - $3333 per month");
colNames.put("CE03", "with earnings greater than $3333 per month");
colNames.put("CNS01", "in agriculture, forestry, fishing and hunting");
colNames.put("CNS02", "in mining, quarrying, and oil and gas extraction");
colNames.put("CNS03", "in utilities");
colNames.put("CNS04", "in construction");
colNames.put("CNS05", "in manufacturing");
colNames.put("CNS06", "in wholesale trade");
colNames.put("CNS07", "in retail trade");
colNames.put("CNS08", "in transportation and warehousing");
colNames.put("CNS09", "in information");
colNames.put("CNS10", "in finance and insurance");
colNames.put("CNS11", "in real estate");
colNames.put("CNS12", "in professional, scientific and technical services");
colNames.put("CNS13", "in management");
colNames.put("CNS14", "in administration, support, and waste management");
colNames.put("CNS15", "in educational services");
colNames.put("CNS16", "in healthcare and social assistance");
colNames.put("CNS17", "in arts, entertainment and recreation");
colNames.put("CNS18", "in accommodation and food services");
colNames.put("CNS19", "in other services, except public administration");
colNames.put("CNS20", "in public administration");
colNames.put("CR01", "with race White alone");
colNames.put("CR02", "with race Black or African American alone");
colNames.put("CR03", "with race American Indian or Alaska Native alone");
colNames.put("CR04", "with race Asian alone");
colNames.put("CR05", "with race Native Hawaiian or Other Pacific Islander alone");
colNames.put("CR07", "with two or more racial groups");
colNames.put("CT01", "not Hispanic or Latino");
colNames.put("CT02", "Hispanic or Latino");
colNames.put("CD01", "with less than high school education");
colNames.put("CD02", "with high school education, no college");
colNames.put("CD03", "with some college education or Associate degree");
colNames.put("CD04", "with Bachelor's degree or higher");
colNames.put("CS01", "male");
colNames.put("CS02", "female");
// only in workplace characteristics
colNames.put("CFA01", "at firms aged 0-1 years");
colNames.put("CFA02", "at firms aged 2-3 years");
colNames.put("CFA03", "at firms aged 4-5 years");
colNames.put("CFA04", "at firms aged 6-10 years");
colNames.put("CFA05", "at firms aged 11 or more years");
colNames.put("CFS01", "at firms with 0-19 employees");
colNames.put("CFS02", "at firms with 20-49 employees");
colNames.put("CFS03", "at firms with 50-249 employees");
colNames.put("CFS04", "at firms with 250-499 employees");
colNames.put("CFS05", "at firms with 500 or more employees");
colNames.put("createdate", "Data creation date");
reader.readHeaders();
String[] headers = reader.getHeaders();
// read the file
while (reader.readRecord()) {
long id = Long.parseLong(reader.get(type == LodesType.WORKPLACE ? "w_geocode" : "h_geocode"));
GeobufFeature feat = store.get(id);
String[] line = reader.getValues();
for (int i = 0; i < line.length; i++) {
String col = headers[i];
if (!colNames.containsKey(col))
continue;
String colName;
if (type == LodesType.WORKPLACE) {
if (col.startsWith("CR") || col.startsWith("CD") || col.startsWith("CA"))
colName = "Jobs employing workers " + colNames.get(col);
else if (col.startsWith("CS"))
colName = "Jobs employing " + colNames.get(col) + "s";
else if (col.startsWith("CT"))
colName = "Jobs employing " + colNames.get(col) + " workers";
else
colName = "Jobs " + colNames.get(col);
}
else if (type == LodesType.RESIDENCE) {
if (col.startsWith("CT") || col.startsWith("CS"))
colName = "Workers, " + colNames.get(col);
else
colName = "Workers " + colNames.get(col);
}
else {
throw new IllegalArgumentException("Invalid LODES type");
}
feat.properties.put(colName, Integer.parseInt(line[i]));
}
store.put(feat);
}
reader.close();
}
/** supported lodes types are workplace area characteristics and residence area characteristics */
public static enum LodesType {
WORKPLACE, RESIDENCE
}
}
Now that we've defined classes to handle both the TIGER shapes and the LODES data, we can define a CensusLoader
class that will loop through all the files we've downloaded and:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.stream.Stream;
/**
* Import data from the US Census into a seamless store in S3 or on disk.
*/
public class CensusLoader {
protected static final Logger LOG = LoggerFactory.getLogger(CensusLoader.class);
public static void main (String... args) throws Exception {
File indir = new File(args[0]);
File tiger = new File(indir, "tiger");
ShapeDataStore store = new ShapeDataStore();
// load up the tiger files in parallel
LOG.info("Loading TIGER (geometry)");
Stream.of(tiger.listFiles())
.filter(f -> f.getName().endsWith(".shp"))
.forEach(f -> {
LOG.info("Loading file {}", f);
TigerLineSource src = new TigerLineSource(f);
try {
src.load(store);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
LOG.info("TIGER done");
LOG.info("Loading LODES workforce data");
File workforce = new File(indir, "workforce");
Stream.of(workforce.listFiles())
.filter(f -> f.getName().endsWith(".csv.gz"))
.forEach(f -> {
LOG.info("Loading file {}", f);
try {
new LodesSource(f, LodesSource.LodesType.RESIDENCE).load(store);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
LOG.info("Workforce done");
LOG.info("Loading LODES jobs data");
File jobs = new File(indir, "jobs");
Stream.of(jobs.listFiles())
.filter(f -> f.getName().endsWith(".csv.gz"))
.forEach(f -> {
LOG.info("Loading file {}", f);
try {
new LodesSource(f, LodesSource.LodesType.WORKPLACE).load(store);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
LOG.info("Jobs done");
if (args.length == 1)
store.writeTiles(new File(indir, "tiles"));
else
// write to s3
store.writeTilesToS3(args[1]);
store.close();
}
}
Now, use the same temporary directory we used before. If you omit the S3 bucket name, it will place the tiles in the tiles
directory in the temporary directory.
JAVA_OPTS=-Xmx[several]G mvn exec:java -Dexec.mainClass="com.conveyal.data.census.CensusLoader" -Dexec.args="temporary_dir s3_bucket_name"
The processed data is stored in a directory structure, which is kept in Amazon S3. Census data is split up into zoom-level-11 tiles and stored in GeoBuf files, each in a directory structure as follows: its source/its x coordinate/its y coordinate
. For example, us-census-2012/342/815.pbf
might contain US LODES data and decennial census data for southeastern Goleta, CA.
Since we include enumeration units that are partially in the tile, enumeration units that can fall into two or more tiles. The end-user must de-duplicate which can be done based on IDs. An enumeration unit that is duplicated across tiles will have the same integer ID in both tiles.
Now that we've done all this processing, we can code our extraction process. To start, we define a generic class SeamlessSource
that will load a Geobuf tiles and extract the relevant features, either by our specified bounding box or by specific polygon. We will extend this class later to account either for a local database or an S3 bucket.
import com.conveyal.data.geobuf.GeobufDecoder;
import com.conveyal.data.geobuf.GeobufFeature;
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.geom.prep.PreparedPolygon;
import com.vividsolutions.jts.util.GeometricShapeFactory;
import org.mapdb.DBMaker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import static com.conveyal.data.census.ShapeDataStore.lat2tile;
import static com.conveyal.data.census.ShapeDataStore.lon2tile;
/**
* A tile source for seamless Census extracts
*/
public abstract class SeamlessSource {
// convenience
private static final int ZOOM_LEVEL = ShapeDataStore.ZOOM_LEVEL;
protected static final Logger LOG = LoggerFactory.getLogger(SeamlessSource.class);
private static final GeometryFactory geometryFactory = new GeometryFactory();
/** Extract features by bounding box */
public Map extract(double north, double east, double south, double west, boolean onDisk) throws
IOException {
GeometricShapeFactory factory = new GeometricShapeFactory(geometryFactory);
factory.setCentre(new Coordinate((east + west) / 2, (north + south) / 2));
factory.setWidth(east - west);
factory.setHeight(north - south);
Polygon rect = factory.createRectangle();
return extract(rect, onDisk);
}
/** Extract features by arbitrary polygons */
public Map extract(Geometry bounds, boolean onDisk) throws IOException {
Map ret;
if (onDisk)
ret = DBMaker.tempTreeMap();
else
ret = new HashMap<>();
Envelope env = bounds.getEnvelopeInternal();
double west = env.getMinX(), east = env.getMaxX(), north = env.getMaxY(), south = env.getMinY();
// TODO: use prepared polygons
// figure out how many tiles we're requesting
int minX = lon2tile(west, ZOOM_LEVEL), maxX = lon2tile(east, ZOOM_LEVEL),
minY = lat2tile(north, ZOOM_LEVEL), maxY = lat2tile(south, ZOOM_LEVEL);
int tcount = (maxX - minX + 1) * (maxY - minY + 1);
LOG.info("Requesting {} tiles", tcount);
int fcount = 0;
// read all the relevant tiles
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
InputStream is = getInputStream(x, y);
if (is == null)
// no data in this tile
continue;
// decoder closes input stream as soon as it has read the tile
GeobufDecoder decoder = new GeobufDecoder(new GZIPInputStream(new BufferedInputStream(is)));
while (decoder.hasNext()) {
GeobufFeature f = decoder.next();
// blocks are duplicated at the edges of tiles, no need to import twice
if (ret.containsKey(f.numericId))
continue;
if (!bounds.disjoint(f.geometry)) {
ret.put(f.numericId, f);
fcount++;
if (fcount % 1000 == 0)
LOG.info("Read {} features", fcount);
}
}
}
}
return ret;
}
/** get an input stream for the given tile */
protected abstract InputStream getInputStream(int x, int y) throws IOException;
}
Here we extend our previous generic SeamlessSource
to account for the the case we stored our processed files locally.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Seamless source for the file system.
*/
public class FileSeamlessSource extends SeamlessSource {
private File directory;
public FileSeamlessSource(String path) {
this.directory = new File(path);
}
@Override protected InputStream getInputStream(int x, int y) throws IOException {
File dir = new File(directory, x + "");
File file = new File(dir, y + ".pbf.gz");
if (!file.exists())
return null;
return new FileInputStream(file);
}
}
Below, in this case, we extend SeamlessSource
to account for retrieving from an S3 bucket.
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import java.io.IOException;
import java.io.InputStream;
/**
* A seamless data source based on storage in Amazon S3.
*/
public class S3SeamlessSource extends SeamlessSource {
private static AmazonS3 s3 = new AmazonS3Client();
public final String bucketName;
public S3SeamlessSource(String bucketName) {
this.bucketName = bucketName;
}
@Override
protected InputStream getInputStream(int x, int y) throws IOException {
try {
return s3.getObject(bucketName, String.format("%d/%d.pbf.gz", x, y)).getObjectContent();
} catch (AmazonS3Exception e) {
// there is no data in this tile
if ("NoSuchKey".equals(e.getErrorCode()))
return null;
else
// re-throw, something else is amiss
throw e;
}
}
}
And finally we defining an overarching class that extract our desired features either locally or from S3.
import com.conveyal.data.geobuf.GeobufEncoder;
import com.conveyal.data.geobuf.GeobufFeature;
import com.conveyal.geojson.GeoJsonModule;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Polygon;
import java.io.*;
import java.util.List;
import java.util.Map;
/**
* Extract Census data from a seamless datastore.
*/
public class CensusExtractor {
/**
* The precision to use for output files.
* Set above 6 at your own risk; higher precision files work fine with the reference implementation and with geobuf-java,
* but break with pygeobuf (see https://github.com/mapbox/pygeobuf/issues/21)
*/
private static final int PRECISION = 6;
public static void main (String... args) throws IOException {
if (args.length < 3 || args.length > 6) {
System.err.println("usage: CensusExtractor (s3://bucket|data_dir) n e s w [outfile.json]");
System.err.println(" or: CensusExtractor (s3://bucket|data_dir) boundary.geojson [outfile.json]");
return;
}
SeamlessSource source;
if (!args[0].startsWith("s3://"))
source = new FileSeamlessSource(args[0]);
else
source = new S3SeamlessSource(args[0].substring(5));
long start = System.currentTimeMillis();
Map features;
if (args.length >= 4) {
features = source.extract(Double.parseDouble(args[1]),
Double.parseDouble(args[2]),
Double.parseDouble(args[3]),
Double.parseDouble(args[4]),
false
);
}
else {
// read geojson boundary
ObjectMapper om = new ObjectMapper();
om.registerModule(new GeoJsonModule());
FileInputStream fis = new FileInputStream(new File(args[1]));
FeatureCollection fc = om.readValue(fis, FeatureCollection.class);
fis.close();
features = source.extract(fc.features.get(0).geometry, false);
}
OutputStream out;
long completeTime = System.currentTimeMillis() - start;
System.err.println("Read " + features.size() + " features in " + completeTime + "msec");
if (args.length == 6)
out = new FileOutputStream(new File(args[5]));
else if (args.length == 3)
out = new FileOutputStream(new File(args[2]));
else
out = System.out;
GeobufEncoder encoder = new GeobufEncoder(out, PRECISION);
encoder.writeFeatureCollection(features.values());
encoder.close();
if (out instanceof FileOutputStream)
out.close();
}
// rudimentary geojson classes to deserialize feature collection
public static class FeatureCollection {
public String type;
public Map crs;
public List features;
}
public static class Feature {
public String type;
public Map properties;
public Geometry geometry;
}
}
Now for the fun part. The following command will extract the data stored in the S3 bucket specified, using the bounding box specified, to the geobuf file out.pbf.
JAVA_OPTS=-Xmx[several]G mvn exec:java -Dexec.mainClass="com.conveyal.data.census.CensusExtractor" -Dexec.args="s3://bucket_name n e s w out.pbf"


Ethiopia Yirgacheffe Coffee
Ethiopian Yirgacheffe coffee is one of the worlds most sought after coffees. Since Ethiopia is the birthplace of coffee and it has embedded history as the first coffee growing region, it's no wonder these beans are incredibly popular.  These Ethiopian beans are hand-picked, which makes the quality rank high amongst other coffees. Processed through the wet-processing method, Ethiopian Yirgacheffe's beans are fermented for over 72 hours after having their fruit and pulp removed by the use of natural enzymes. This process allows the Ethiopian Yirgacheffe to absorb the sugars in the coffee fruit, creating a stronger full-body flavor in comparison to the dry-method of processing coffee. Ethiopian Yirgacheffe coffee beans are known for having a warm zing, which makes this coffee bean distinctive enough to rank as one of the finest. However, what makes this African coffee bean stand out is its resonant finish – a highly-flavored mix that does not overpower with an earthy taste. If you are looking for a taste of coffee history, the Ethiopian Yirgacheffe beans have everything your palate could ask for!.


UTC all year.
YACHTING ESSENTIAL
Water
There are four drinking water taps/faucets located within 10 metres of the wharf landing. The tap at the top of the steps has a hose which makes it quick and easy for filling water jugs. The water is free (part of your port dues).
Fuel
Contact Michael Richards at the Marine office, Telephone number: +209 22030. The island also has three service stations for cars and trucks.
Garbage Disposal
The trash cans/bins are located on the waterfront wharf.
St Helenian pound (£) of 100 pence, fixed at parity with £ sterling. Sterling currency can be used everywhere; change is given in St. Helena Pounds.
Before leaving all money should be changed back to sterling, as the notes are not valid outside of St. Helena and Ascension Island.
There is one bank in Jamestown. See Banks for further info. It's easy to get caught out here as there are no ATMs. The bank can do cash advances on Visa or Mastercard but there is a service charge.
A few shops and businesses do accept credit cards. The Yacht Club and the Consulate Hotel accept credit cards.
Cruisers however recommend that the easiest solution is to arrive in St Helena with Pound Sterling from South Africa.
International dialing code in St Helena is +290.
Sure (ex. Cable & Wireless) now offers 2G and 4G LTE mobile network. Prepaid SIM cards can be purchased in their office in Jamestown. Data bundles are available and reception (internet usage) is now possible on board. 4G internet is very fast, but expensive comparing to other countries and cheaper than WiFi hot spots on island if it is not used for large data transfers.
Last updated May 2016.
Buses
The public transport system on St Helena is fairly new and has a very limited service. White buses marked with Route A, B, C, D, or E cover the entire island. The maximum fare is £2, (about $3 USD) each way per person. The Tourist Office will give you a copy of the bus schedule.
Hitch-Hiking
Another way to get around the island is to hitch-hike: This is one of the few places on the planet were hitch-hikers can easily obtain a safe ride. Getting a lift shouldn't take you long.
Car Hire
Visitors have the option of booking tours through the Tourist Office, car rental or taxis.
It costs £12-15 per day to hire a car and driving is not difficult with the speed limit only 40mph, but prepare to use your horn.Driving is on the left hand side of the road.
Taxis
The main taxi stand is behind the tourist office and another by the main jetty. Taxis are un-metred so agree a price before taking a ride.
Various taxis offer tours of the island (at £6 per person). Corker’s Tours ( email ) have a 1929 Chevrolet bus for larger groups.
Airport
The U.K. government decided in 2010 that the long term economic independence of the island would be best served by the building of an airport. This was due to open in May 2016 however problems have been encountered with high winds, so it is currently still not open for commercial flights.
Sadly, once the airport is open, the current Royal Mail Ship "St Helena" (predecessors of which have served the island since 1502), may be be retired.
Royal Mail Ship "St Helena"
Andrew Weir Shipping Ltd
Tel +44 0151 4795555, Fax: +44 0151 2362644
www.aws.co.uk.
Solomon and Company Plc. (Agent on St. Helena)
Tel: +290 2380, Fax: +290 2523
Email<EMAIL_ADDRESS>Ambulance - Dial 911
Fire, Police, Sea Rescue - Dial 999
IMRAY AND ADLARD COLES PILOT BOOKS are available at a discounted price for Noonsite.com users via World Cruising Club
South Atlantic Circuit
By Tom Morgan, RCC Pilotage Foundation
Publisher: Imray, Norie & Wilson - 1st Edition 2002
ISBN 13:<PHONE_NUMBER>338
South Atlantic Islands
Free download from the RCC Pilotage Foundation Website
By Pete Hill (2010)
There is an excellent PDF available on line with useful local information for visiting yachts at the St Helena tourist board website.
www.sthelenatourism.com
St Helena Government
The government tourist office is most helpful and can be contacted at sthelena.tourism@helanta.sh


{% extends "layout.html" %} {% block content %}
This {{ context.reduction_percentage }}% text reduction will save you {{ context.minutes_saved }} minutes. Way to go! 🎉
{% elif context.reduction_percentage %}The text was reduced by {{ context.reduction_percentage }}%. Enjoy the extra time 💖
{% endif %} {% for header, summary in context.summary_dict.items() %}{{ summary }}
It looks like we weren't able to parse that. Maybe try with a different website.
{% endif %} {% endblock content %}


|
Native Library
|
#include <StringBuffer.hpp>
Public Member Functions | |
| StringBuffer () | |
| StringBuffer (CharSequence *sequence) | |
| StringBuffer (int capacity) | |
| StringBuffer (String originalString) | |
| StringBuffer (const StringBuffer &other) | |
| StringBuffer & | append (Object *object) |
| StringBuffer & | append (float floatValue) |
| StringBuffer & | append (string stringToAppend) |
| StringBuffer & | append (boolean boolValue) |
| StringBuffer & | append (CharSequence *sequence) |
| StringBuffer & | append (double doubleValue) |
| StringBuffer & | append (char charValue) |
| StringBuffer & | append (String stringToAppend) |
| StringBuffer & | append (int intValue) |
| StringBuffer & | append (long longValue) |
| StringBuffer & | append (StringBuffer stringBuffer) |
| StringBuffer & | append (string stringToAppend, int offset, int len) |
| StringBuffer & | append (CharSequence *sequence, int start, int end) |
| StringBuffer & | appendCodePoint (int codePoint) |
| int | capacity () |
| char | charAt (int index) |
| int | codePointAt (int index) |
| int | codePointBefore (int index) |
| int | codePointCount (int beginIndex, int endIndex) |
| StringBuffer & | deletes (int start, int end) |
| StringBuffer & | deleteCharAt (int index) |
| void | ensureCapacity (int minimumCapacity) |
| string | getValue () |
| int | indexOf (String stringToGetIndex) |
| int | indexOf (String stringToGetIndex, int fromIndex) |
| StringBuffer & | insert (int offset, float floatValue) |
| StringBuffer & | insert (int offset, CharSequence *charSequence) |
| StringBuffer & | insert (int offset, boolean boolValue) |
| StringBuffer & | insert (int offset, string stringToInsert) |
| StringBuffer & | insert (int offset, char charValue) |
| StringBuffer & | insert (int offset, String stringToInsert) |
| StringBuffer & | insert (int offset, long longValue) |
| StringBuffer & | insert (int offset, Object *object) |
| StringBuffer & | insert (int offset, int intValue) |
| StringBuffer & | insert (int offset, double doubleValue) |
| StringBuffer & | insert (int destinationOffset, CharSequence *sequence, int start, int end) |
| StringBuffer & | insert (int index, string stringToInsert, int offset, int len) |
| int | lastIndexOf (String stringToGetIndex) |
| int | lastIndexOf (String stringToGetIndex, int fromIndex) |
| int | length () |
| int | offsetByCodePoints (int index, int codePointOffset) |
| StringBuffer & | replace (int start, int end, String stringToReplace) |
| StringBuffer & | reverse () |
| void | setCharAt (int index, char charValue) |
| void | setLength (int newLength) |
| String | subString (int start) |
| String | subString (int start, int end) |
| String | toString () |
| void | trimToSize () |
| StringBuffer & | operator= (const StringBuffer &other) |
| ~StringBuffer () | |
| Public Member Functions inherited from Java::Lang::StringBufferUnSafe | |
| StringBufferUnSafe () | |
| StringBufferUnSafe (CharSequence *sequence) | |
| StringBufferUnSafe (int capacity) | |
| StringBufferUnSafe (String originalString) | |
| StringBufferUnSafe (const StringBufferUnSafe &other) | |
| StringBufferUnSafe & | append (Object *object) |
| StringBufferUnSafe & | append (float floatValue) |
| StringBufferUnSafe & | append (string stringToAppend) |
| StringBufferUnSafe & | append (boolean boolValue) |
| StringBufferUnSafe & | append (CharSequence *sequence) |
| StringBufferUnSafe & | append (double doubleValue) |
| StringBufferUnSafe & | append (char charValue) |
| StringBufferUnSafe & | append (String stringToAppend) |
| StringBufferUnSafe & | append (int intValue) |
| StringBufferUnSafe & | append (long longValue) |
| StringBufferUnSafe & | append (StringBufferUnSafe stringBufferUnSafe) |
| StringBufferUnSafe & | append (string stringToAppend, int offset, int len) |
| StringBufferUnSafe & | append (CharSequence *sequence, int start, int end) |
| StringBufferUnSafe & | appendCodePoint (int codePoint) |
| int | capacity () |
| char | charAt (int index) |
| int | codePointAt (int index) |
| int | codePointBefore (int index) |
| int | codePointCount (int beginIndex, int endIndex) |
| StringBufferUnSafe & | deletes (int start, int end) |
| StringBufferUnSafe & | deleteCharAt (int index) |
| void | ensureCapacity (int minimumCapacity) |
| string | getValue () |
| int | indexOf (String stringToGetIndex) |
| int | indexOf (String stringToGetIndex, int fromIndex) |
| StringBufferUnSafe & | insert (int offset, float floatValue) |
| StringBufferUnSafe & | insert (int offset, CharSequence *charSequence) |
| StringBufferUnSafe & | insert (int offset, boolean boolValue) |
| StringBufferUnSafe & | insert (int offset, string stringToInsert) |
| StringBufferUnSafe & | insert (int offset, char charValue) |
| StringBufferUnSafe & | insert (int offset, String stringToInsert) |
| StringBufferUnSafe & | insert (int offset, long longValue) |
| StringBufferUnSafe & | insert (int offset, Object *object) |
| StringBufferUnSafe & | insert (int offset, int intValue) |
| StringBufferUnSafe & | insert (int offset, double doubleValue) |
| StringBufferUnSafe & | insert (int destinationOffset, CharSequence *sequence, int start, int end) |
| StringBufferUnSafe & | insert (int index, string stringToInsert, int offset, int len) |
| int | lastIndexOf (String stringToGetIndex) |
| int | lastIndexOf (String stringToGetIndex, int fromIndex) |
| int | length () |
| int | offsetByCodePoints (int index, int codePointOffset) |
| StringBufferUnSafe & | replace (int start, int end, String stringToReplace) |
| StringBufferUnSafe & | reverse () |
| void | setCharAt (int index, char charValue) |
| void | setLength (int newLength) |
| String | subString (int start) |
| String | subString (int start, int end) |
| String | toString () |
| void | trimToSize () |
| StringBufferUnSafe & | operator= (const StringBufferUnSafe &other) |
| ~StringBufferUnSafe () | |
| Public Member Functions inherited from Java::Lang::Object | |
| virtual string | toString () const |
| virtual boolean | equals (const Object &o) const |
| Class< Object > | getClass () |
| virtual long | hashCode () const |
| void | notify () |
| void | notifyAll () |
| void | wait () |
| void | wait (long timeout) |
| void | wait (long timeout, int nanos) |
| boolean | operator== (const Object &target) const |
| boolean | operator!= (const Object &target) const |
Additional Inherited Members | |
| Protected Member Functions inherited from Java::Lang::Object | |
| template<typename E > | |
| E | clone () |
| void | finalize () |
| Protected Attributes inherited from Java::Lang::StringBufferUnSafe | |
| string | original = nullptr |
| int | currentLength = 0 |
| int | currentCapacity = 0 |
An inheritance class with thread-safe
| StringBuffer::StringBuffer | ( | ) |
Constructs a string buffer with no characters in it and an initial capacity of 16 characters.
|
explicit |
Constructs a string buffer that contains the same characters as the specified CharSequence.
| sequence |
|
explicit |
Constructs a string buffer with no characters in it and the specified initial capacity.
| capacity |
| NegativeArraySizeException | if capacity is negative |
|
explicit |
Constructs a string buffer initialized to the contents of the specified string.
| originalString |
| StringBuffer::StringBuffer | ( | const StringBuffer & | other | ) |
Copy constructor
| other |
|
default |
Destructor, free memory allocated for original
| StringBuffer & StringBuffer::append | ( | Object * | object | ) |
Appends the string representation of the Object argument.
| object |
| StringBuffer & StringBuffer::append | ( | float | floatValue | ) |
Appends the string representation of the float argument
| floatValue |
| StringBuffer & StringBuffer::append | ( | string | stringToAppend | ) |
Appends the string representation of the char array argument to this sequence.
| stringToAppend |
| StringBuffer & StringBuffer::append | ( | boolean | boolValue | ) |
Appends the string representation of the boolean argument
| boolValue |
| StringBuffer & StringBuffer::append | ( | CharSequence * | sequence | ) |
Appends the specified CharSequence to this sequence.
| sequence |
| StringBuffer & StringBuffer::append | ( | double | doubleValue | ) |
Appends the string representation of the double argument
| doubleValue |
| StringBuffer & StringBuffer::append | ( | char | charValue | ) |
Appends the string representation of the char argument
| charValue |
| StringBuffer & StringBuffer::append | ( | String | stringToAppend | ) |
Appends the string representation of char array argument to this sequence.
| stringToAppend |
| StringBuffer & StringBuffer::append | ( | int | intValue | ) |
Appends the string representation of the int argument
| intValue |
| StringBuffer & StringBuffer::append | ( | long | longValue | ) |
Appends the string representation of the long argument
| longValue |
| StringBuffer & StringBuffer::append | ( | StringBuffer | stringBuffer | ) |
Appends the specified StringBuffer to this sequence.
| stringBuffer |
| StringBuffer & StringBuffer::append | ( | string | stringToAppend, |
| int | offset, | ||
| int | len | ||
| ) |
Appends the string representation of a subarray of the char array argument to this sequence. Characters of the char array str, starting at index offset, are appended, in order, the length of subarray is equal to len
| stringToAppend | |
| offset | |
| len |
| IndexOutOfBoundsException | if offset < 0 or len < 0 or offset+len > str.length |
| StringBuffer & StringBuffer::append | ( | CharSequence * | sequence, |
| int | start, | ||
| int | end | ||
| ) |
Appends a subsequence of the specified CharSequence to this sequence. starting at index start, are appended, in order, to the contents of this sequence up to the (exclusive) index end. If start is negative or bigger than end or bigger than seq's length, throw IndexOutOfBoundException
| sequence | |
| start | |
| end |
| IndexOutOfBoundException | If start is negative or bigger than end or bigger than seq's length |
| StringBuffer & StringBuffer::appendCodePoint | ( | int | codePoint | ) |
Appends the string representation of the codePoint argument to this sequence. *
| codePoint |
| int StringBuffer::capacity | ( | ) |
Return current capacity of this StringBuffer
| char StringBuffer::charAt | ( | int | index | ) |
Return character at specified index
| index |
| IndexOutOfBoundsException | - if index is negative or greater than or equal to length(). |
| int StringBuffer::codePointAt | ( | int | index | ) |
Returns the character (Unicode code point) at the specified index. If the char value specified at the given index is in the high-surrogate range, the following index is less than the length of this sequence, and the char value at the following index is in the low-surrogate range, then the supplementary code point corresponding to this surrogate pair is returned. Otherwise, the char value at the given index is returned.
| index |
| IndexOutOfBoundException | if index is negative or greater than or equal to length(). |
| int StringBuffer::codePointBefore | ( | int | index | ) |
Returns the character (Unicode code point) before the specified index. If the char value at (index - 1) is in the low-surrogate range, (index - 2) is not negative, and the char value at (index - 2) is in the high-surrogate range, then the supplementary code point value of the surrogate pair is returned. If the char value at index - 1 is an unpaired low-surrogate or a high-surrogate, the surrogate value is returned.
| index |
| IndexOutOfBoundException | if index is negative or greater than or equal to length(). |
| int StringBuffer::codePointCount | ( | int | beginIndex, |
| int | endIndex | ||
| ) |
Returns the number of Unicode code points in the specified text range of this sequence. The text range begins at the specified beginIndex and extends to the char at index endIndex - 1
| beginIndex | |
| endIndex |
| StringBuffer & StringBuffer::deleteCharAt | ( | int | index | ) |
Removes the char at the specified position in this sequence.
| index |
| StringIndexOutOfBoundsException | - if the index is negative or greater than or equal to length(). |
| StringBuffer & StringBuffer::deletes | ( | int | start, |
| int | end | ||
| ) |
Removes the characters in a substring of this sequence. The substring begins at the specified start and extends to the character at index end - 1 or to the end of the sequence if no such character exists. If start is equal to end, no changes are made.
| start,inclusive | |
| end,exclusive |
| StringIndexOutOfBound | - if start is negative, greater than length(), or greater than end. |
| void StringBuffer::ensureCapacity | ( | int | minimumCapacity | ) |
Ensures that the capacity is at least equal to the specified minimum. The new capacity is the larger than the minimumCapacity argument and twice the old capacity plus 2. If minimumCapacity is non-positive or less or equal to this capacity, return
| minimumCapacity |
| string StringBuffer::getValue | ( | ) |
Characters are copied from this sequence into the destination character array.
| sourceBegin | |
| sourceEnd | |
| destination | |
| destinationBegin |
| IndexOutOfBoundsException | - if : sourceBegin is negative destinationBegin is negative the sourceBegin argument is greater than the sourceEnd argument. sourceEnd is greater than this.length(). destinationBegin+sourceEnd-sourceBegin is greater than destination length Return the string value of this StringBuffer |
| int StringBuffer::indexOf | ( | String | stringToGetIndex | ) |
Returns the index within this string of the first occurrence of the specified substring. The integer returned is the smallest value
| stringToGetIndex |
| int StringBuffer::indexOf | ( | String | stringToGetIndex, |
| int | fromIndex | ||
| ) |
Returns the index within this string of the first occurrence of the specified substring, starting at the specified index. The integer returned is the smallest value
| stringToGetIndex | |
| fromIndex |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| float | floatValue | ||
| ) |
Inserts the string representation of the float argument into this sequence. The offset argument must be greater than or equal to 0, and less than or equal to the length of this sequence.
| offset | |
| floatValue |
| StringIndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| CharSequence * | charSequence | ||
| ) |
Inserts the specified CharSequence into this sequence. The characters of the CharSequence argument are inserted, in order, into this sequence at the indicated offset, moving up any characters originally above that position If charSequence is null, then the four characters "null" are inserted into this sequence.
| offset | |
| charSequence |
| IndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| boolean | boolValue | ||
| ) |
Inserts the string representation of the bool argument into this sequence. The offset argument must be greater than or equal to 0, and less than or equal to the length of this sequence.
| offset | |
| boolValue |
| IndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| string | stringToInsert | ||
| ) |
Inserts the string representation of the char array argument into this sequence. The characters of the array argument are inserted into the contents of this sequence at the position indicated by offset. The length of this sequence increases by the length of the argument.
| offset | |
| stringToInsert |
| StringIndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| char | charValue | ||
| ) |
Inserts the string representation of the char argument into this sequence. The offset argument must be greater than or equal to 0, and less than or equal to the length of this sequence.
| offset | |
| charValue |
| StringIndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| String | stringToInsert | ||
| ) |
Inserts the string into this character sequence. The characters of the String argument are inserted, in order, into this sequence at the indicated offset, moving up any characters originally above that position and increasing the length of this sequence by the length of the argument. If str is null, then the four characters "null" are inserted into this sequence.
| offset | |
| stringToInsert |
| StringIndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| long | longValue | ||
| ) |
Inserts the string representation of the long argument into this sequence. The offset argument must be greater than or equal to 0, and less than or equal to the length of this sequence.
| offset | |
| longValue |
| StringIndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| Object * | object | ||
| ) |
Inserts the string representation of the Object argument into this character sequence. The offset argument must be greater than or equal to 0, and less than or equal to the length of this sequence.
| offset | |
| object |
| StringIndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| int | intValue | ||
| ) |
Inserts the string representation of the int argument into this sequence. The offset argument must be greater than or equal to 0, and less than or equal to the length of this sequence.
| offset | |
| intValue |
| StringIndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | offset, |
| double | doubleValue | ||
| ) |
Inserts the string representation of the double argument into this sequence. The offset argument must be greater than or equal to 0, and less than or equal to the length of this sequence.
| offset | |
| doubleValue |
| StringIndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | destinationOffset, |
| CharSequence * | sequence, | ||
| int | start, | ||
| int | end | ||
| ) |
The subsequence of the argument s specified by start and end are inserted, in order, into this sequence at the specified destination offset, moving up any characters originally above that position. The destinationOffset argument must be greater than or equal to 0, and less than or equal to length The start argument must be non negative, and not greater than end. The end argument must be greater than or equal to start, and less than or equal to the length of sequence. If sequence is null, four characters "null" will be inserted
| destinationOffset | |
| sequence | |
| start | |
| end |
| IndexOutOfBoundsException | - if the offset is invalid. |
| StringBuffer & StringBuffer::insert | ( | int | index, |
| string | stringToInsert, | ||
| int | offset, | ||
| int | len | ||
| ) |
Inserts the string representation of a subarray of the str array argument into this sequence. The subarray begins at the specified offset and extends len chars. The subarray is insert at position index
| index | |
| stringToInsert | |
| offset | |
| len |
| StringIndexOutOfBoundsException | - if index is negative or greater than length(), or offset or len are negative, or (offset+len) is greater than str.length. |
| int StringBuffer::lastIndexOf | ( | String | stringToGetIndex | ) |
Returns the index within this string of the rightmost occurrence of the specified substring. The rightmost empty string "" is considered to occur at the index value this.length(). T he returned index is the largest value If no such value of stringToGetIndex exists, then -1 is returned.
| stringToGetIndex |
| int StringBuffer::lastIndexOf | ( | String | stringToGetIndex, |
| int | fromIndex | ||
| ) |
Returns the index within this string of the last occurrence of the specified substring. The integer returned is the largest value If no such value exists, then -1 is returned.
| stringToGetIndex | |
| fromIndex |
| int StringBuffer::length | ( | ) |
Return the current number of used char of this sequence
| int StringBuffer::offsetByCodePoints | ( | int | index, |
| int | codePointOffset | ||
| ) |
Returns the index within this sequence that is offset from the given index by codePointOffset code points. Unpaired surrogates within the text range given by index and codePointOffset count as one code point each.
| index | |
| codePointOffset |
| IndexOutOfBoundsException |
| StringBuffer & StringBuffer::operator= | ( | const StringBuffer & | other | ) |
Overload operator =
| StringBuffer & StringBuffer::replace | ( | int | start, |
| int | end, | ||
| String | stringToReplace | ||
| ) |
Replaces the characters in a substring of this sequence with characters in the specified String. The substring begins at the specified start and extends to the character at index end - 1 or to the end of the sequence if no such character exists. First the characters in the substring are removed and then the specified String is inserted at start.
| start | |
| end | |
| stringToReplace |
| StringIndexOutOfBoundsException | - if start is negative, greater than length(), or greater than end. |
| StringBuffer & StringBuffer::reverse | ( | ) |
Causes this character sequence to be replaced by the reverse of the sequence. If there are any surrogate pairs included in the sequence, these are treated as single characters for the reverse operation.
| void StringBuffer::setCharAt | ( | int | index, |
| char | charValue | ||
| ) |
Set the character at the specified index to charValue.
| index | |
| charValue |
| IndexOutOfBoundsException | - if index is negative or greater than or equal to length(). |
| void StringBuffer::setLength | ( | int | newLength | ) |
Sets the length of the character sequence. The sequence is changed to a new character sequence whose length is specified by the argument.
| newLength |
| String StringBuffer::subString | ( | int | start | ) |
Returns a new character sequence that is a subsequence of this sequence. An invocation of this method of the form
| start | |
| end |
| IndexOutOfBoundsException | - if start or end are negative, if end is greater than length(), or if start is greater than end |
| start |
| StringIndexOutOfBoundsException | - if start is less than zero, or greater than the length of this object. |
| String StringBuffer::subString | ( | int | start, |
| int | end | ||
| ) |
Returns a new String that contains a subsequence of characters currently contained in this sequence. The substring begins at the specified start and extends to the character at index end - 1.
| start | |
| end |
| StringIndexOutOfBoundsException | - if start or end are negative or greater than length(), or start is greater than end. |
| String StringBuffer::toString | ( | ) |
Returns a string representing the data in this sequence. A new String object is allocated and initialized to contain the character represented by this object.
| void StringBuffer::trimToSize | ( | ) |
Attempts to reduce storage used for the character sequence. If the buffer is larger than necessary to hold its current sequence of characters, then it may be resized to become more space efficient.


Commander of Battlestar Galactica
Wikipedia
A fictional character portrayed by Edward James Olmos[2] in the re-imagined Battlestar Galactica television series produced and aired by the SyFy cable network. He is one of the main characters, a reimagining of Commander Adama from the 1978 Battlestar Galactica series played by Lorne Greene.
Commander at Battlestar Galactica
Mar 2000 – Present • Skill D, Skill E, Skill F
Junior Commander at Battlestar Lesscool
May 1980 – Mar 2000 • Skill A, Skill B, Skill C
Bachelor of Battlestar Commandering with Distinction
Battlestar War Camp
1975 – 1980
4 year degree completed in 3 years
6.54GPA (14 High Distinctions, 9 Distinctions, 1 Credit, 0 Passes, 0 Fails)


A package directory is simply one that is shared between the global system and the zone via a loopback mount. Because processes running within a zone need access to system programs and files like those in /usr and /lib, these directories are almost always shared. This form can be used to define additional shared directories, such as /opt, for other programs that all zones need access to.


Source code for sap.appendix.appendix_j
"""
Appendix J: Seasonal efficiency for solid fuel boilers from test data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This appendix specifies how to obtain a seasonal efficiency from test data on a solid
fuel boiler that is provided in the Product Characteristics Database. A database
record for a solid fuel boiler includes:
- SAP seasonal efficiency, %
- Fuel input, heat to water and heat to room from test at full load, kW
- Fuel input, heat to water and heat to room from test at part load, kW
All efficiency values are gross (net-to-gross conversion factors are given in Table E4).
"""
from sap.heating_system_types import HeatingSystem
from sap.sap_types import HeatingTypes
[docs]def solid_fuel_boiler_from_pcdf(pcdf_data, fuel, use_immersion_in_summer):
"""
Implements Appendix J
:param pcdf_data:
:param fuel:
:param use_immersion_in_summer:
:return:
"""
if pcdf_data['seasonal_effy'] != '':
effy = float(pcdf_data['seasonal_effy'])
elif pcdf_data['part_load_fuel_use'] != '':
# FIXME
raise NotImplementedError()
# !!! Need to tests for inside/outside of heated space
nominal_effy = 100 * (pcdf_data['nominal_heat_to_water'] + pcdf_data['nominal_heat_to_room']) / pcdf_data[
'nominal_fuel_use']
part_load_effy = 100 * (pcdf_data['part_load_heat_to_water'] + pcdf_data['part_load_heat_to_room']) / pcdf_data[
'part_load_fuel_use']
effy = 0.5 * (nominal_effy + part_load_effy)
else:
nominal_effy = 100 * (
float(pcdf_data['nominal_heat_to_water']) + float(pcdf_data['nominal_heat_to_room'])) / float(
pcdf_data['nominal_fuel_use'])
effy = .975 * nominal_effy
sys = HeatingSystem(HeatingTypes.regular_boiler, # !!!
effy,
effy,
summer_immersion=use_immersion_in_summer,
has_flue_fan=False, # !!!
has_ch_pump=True,
table2b_row=2, # !!! Solid fuel boilers can only have indirect boiler?
default_secondary_fraction=0.1, # !!! Assumes 10% secondary fraction
fuel=fuel)
sys.responsiveness = .5 # !!! Needs to depend on "main type" input
sys.has_warm_air_fan = False
return sys


Sources: Wikipedia. Titles of events have been phrased by David Huynh, author of this timeline example. The phrasing might not be of journalistic quality. The information in this example should not be used as an official source.
Timeline version .
Sources: Wikipedia. Titles of events have been phrased by David Huynh, author of this timeline example. The phrasing might not be of journalistic quality. The information in this example should not be used as an official source.
Timeline version .


Future Plans
Administer the Platform, Asset Management, Data Analysis, Web/App Personalisation, Journeys, enhancements, Schema Configuration, Integration/Platform
Whilst we’re all about automating your customer journeys and marketing campaigns, sometimes we want to focus on making sure the platform stays easy to use, so we’re making some changes to make it easier to manage the assets, users, exceptions and other parts of the platform. We’re looking at what you do and we’re going to make it easier.
Adding some more spice to the way you can send Campaigns. Want to send bespoke content out to one customer? Want to make sure you’ve got the Campaign setup right to go out? Share and improve the way you use content in your campaigns.
You’ve been collecting all this data, building audiences and sending campaigns. Now go to the next level of data insight and ability to take action on that knowledge of your customers with easy integration to your other data tools and make use of our ML models.
Land your customers on personalised pages as part of their end to end journey after clicking on an email.
We’re adding more advanced options to Journeys to direct customers into the right funnel. We’re adding better ways to test and validate the Journey before it goes live.
Setting up schema and getting the data right is hard, it’s important, that’s why it’s hard. Let our system interrogate and help you build and manage your data better.
We know you can meet all your marketing needs using the Intilery Platform, but hey, you still have some systems running that are deeply integrated with another platform, don’t worry, we got you covered as we allow you to integrate with other systems directly or through platforms like zapier.


Welcome back!
Tricentrix Data Analytics platform offers custom
BI Solutions
that deliver
insights
that drives positive results which impact business performance, efficiency, and quality.
HOME
ABOUT
SERVICES
COMPEENCIES
Login below to get started
Login


Neil Warnock has had an incredible career - let's hope Cardiff is not the last we see of him
In this week's EFL on Quest column - pundit Ian Holloway has his say on Neil Warnock's surprising departure from Cardiff and his replacement Neil Harris
by Ian Holloway, https://www.mirror.co.uk/authors/ian-holloway/Neil Warnock has left Cardiff - and it's a difficult situation to assess.
I was there at the weekend, I watched their game. There was nothing wrong with his team. They hit the bar twice and unfortunately Bristol City's shot went in from 30 yards. That's the close margins of the Championship.
Only their owners will know what they're thinking and where they're going. I would have thought Neil Warnock was the right man to get them back up.
For me, there aren't any better managers for getting teams promoted than Neil. Maybe there is more to it - I really don't know.
From afar it doesn't look like they're struggling. There is a long part of the season left and from the performance that I saw - I don't think there's a great deal wrong.
Neil has had an incredible career. What he achieved at Rotherham was absolutely sensational. Then he's gone straight from there to Cardiff - they were in the bottom three - and he got them promoted.
He had a great chance to keep them up but for the terrible tragedy involving Emiliano Sala. Everyone knew they needed a centre-forward and it was horrendous.
I'd like to think Neil has got more left in him - but that must have knocked a lot out of him. He's a very personable guy who gets very close to his players.
But I hope Cardiff is not his last job.
Neil Harris has replaced him and he is one of a number of young managers out there who deserve another chance.
Cardiff is a fantastic club with a massive support and Neil Harris is a very lucky man in my opinion. Good luck to him.
Ian Holloway is a pundit on EFL on Quest throughout the season. Quest is the home of EFL highlights broadcasting every round of fixtures across the leagues. Also available on desktop and app via dplay
Barnsley need to make a decision - and quick
The situation at Barnsley is very strange. It looked as though all was rosy after a great promotion last season. I don't think anyone outside of the club thought they would go up.
They had a terrific run, seemed to get better and better but lost players in the summer, which makes it tough.
Barnsley have to make a decision very quickly. I don't think a caretaker manager who hasn't won in five games is the way to go - they need some experience in there.
They need a manager who is used to managing to get that team going. They are falling adrift and that is the last thing they want.
But there are a lot of games coming up and things can change very quickly. But they need to make their mind up.


Legal Disclaimer
The recipes found on this site are for informational purposes only. Recipe World is not responsible for any demage or harm that results from following any of the directions or consuming any of the foods.
The recipes found on this site are for informational purposes only. Recipe World is not responsible for any demage or harm that results from following any of the directions or consuming any of the foods.


queue module
Use a queue to solve the Josephus problem.
Some people are standing in a circle, numbered from 1 to n. Starting from 1, k people are skipped and the next one is eliminated. This process continues, always with the same k, starting from the person after the eliminated one. What is the initial position of the last person standing?
More details of the problem and its mathematical solution are on Wikipedia. This program solves the problem by simulation.
- examples.queue.eliminated(people, skip)
Return a list of the positions of people as they are eliminated.
The position of the last person standing is at the end of the list. Assume people is a positive integer. Assume skip is a non-negative integer. For example:
>>> eliminated(3, 0) [1, 2, 3] >>> eliminated(3, 1) [2, 1, 3] >>> eliminated(3, 4) [2, 3, 1]